You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

set.h 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * Frozen
  3. * Copyright 2016 QuarksLab
  4. *
  5. * Licensed to the Apache Software Foundation (ASF) under one
  6. * or more contributor license agreements. See the NOTICE file
  7. * distributed with this work for additional information
  8. * regarding copyright ownership. The ASF licenses this file
  9. * to you under the Apache License, Version 2.0 (the
  10. * "License"); you may not use this file except in compliance
  11. * with the License. You may obtain a copy of the License at
  12. *
  13. * http://www.apache.org/licenses/LICENSE-2.0
  14. *
  15. * Unless required by applicable law or agreed to in writing,
  16. * software distributed under the License is distributed on an
  17. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  18. * KIND, either express or implied. See the License for the
  19. * specific language governing permissions and limitations
  20. * under the License.
  21. */
  22. #ifndef FROZEN_SET_H
  23. #define FROZEN_SET_H
  24. #include "frozen/bits/algorithms.h"
  25. #include "frozen/bits/basic_types.h"
  26. #include "frozen/bits/constexpr_assert.h"
  27. #include "frozen/bits/version.h"
  28. #include <utility>
  29. namespace frozen {
  30. template <class Key, std::size_t N, class Compare = std::less<Key>> class set {
  31. using container_type = bits::carray<Key, N>;
  32. Compare less_than_;
  33. container_type keys_;
  34. public:
  35. /* container typedefs*/
  36. using key_type = Key;
  37. using value_type = Key;
  38. using size_type = typename container_type::size_type;
  39. using difference_type = typename container_type::size_type;
  40. using key_compare = Compare;
  41. using value_compare = Compare;
  42. using reference = typename container_type::const_reference;
  43. using const_reference = reference;
  44. using pointer = typename container_type::const_pointer;
  45. using const_pointer = pointer;
  46. using iterator = typename container_type::const_iterator;
  47. using reverse_iterator = typename container_type::const_reverse_iterator;
  48. using const_iterator = iterator;
  49. using const_reverse_iterator = reverse_iterator;
  50. public:
  51. /* constructors */
  52. constexpr set(const set &other) = default;
  53. constexpr set(container_type keys, Compare const & comp)
  54. : less_than_{comp}
  55. , keys_(bits::quicksort(keys, less_than_)) {
  56. }
  57. explicit constexpr set(container_type keys)
  58. : set{keys, Compare{}} {}
  59. constexpr set(std::initializer_list<Key> keys, Compare const & comp)
  60. : set{container_type{keys}, comp} {
  61. constexpr_assert(keys.size() == N, "Inconsistent initializer_list size and type size argument");
  62. }
  63. constexpr set(std::initializer_list<Key> keys)
  64. : set{keys, Compare{}} {}
  65. /* capacity */
  66. constexpr bool empty() const { return !N; }
  67. constexpr size_type size() const { return N; }
  68. constexpr size_type max_size() const { return N; }
  69. /* lookup */
  70. constexpr std::size_t count(Key const &key) const {
  71. return bits::binary_search<N>(keys_.begin(), key, less_than_);
  72. }
  73. constexpr const_iterator find(Key const &key) const {
  74. const_iterator where = lower_bound(key);
  75. if ((where != end()) && !less_than_(key, *where))
  76. return where;
  77. else
  78. return end();
  79. }
  80. constexpr std::pair<const_iterator, const_iterator> equal_range(Key const &key) const {
  81. auto const lower = lower_bound(key);
  82. if (lower == end())
  83. return {lower, lower};
  84. else
  85. return {lower, lower + 1};
  86. }
  87. constexpr const_iterator lower_bound(Key const &key) const {
  88. auto const where = bits::lower_bound<N>(keys_.begin(), key, less_than_);
  89. if ((where != end()) && !less_than_(key, *where))
  90. return where;
  91. else
  92. return end();
  93. }
  94. constexpr const_iterator upper_bound(Key const &key) const {
  95. auto const where = bits::lower_bound<N>(keys_.begin(), key, less_than_);
  96. if ((where != end()) && !less_than_(key, *where))
  97. return where + 1;
  98. else
  99. return end();
  100. }
  101. /* observers */
  102. constexpr key_compare key_comp() const { return less_than_; }
  103. constexpr key_compare value_comp() const { return less_than_; }
  104. /* iterators */
  105. constexpr const_iterator begin() const { return keys_.begin(); }
  106. constexpr const_iterator cbegin() const { return keys_.cbegin(); }
  107. constexpr const_iterator end() const { return keys_.end(); }
  108. constexpr const_iterator cend() const { return keys_.cend(); }
  109. constexpr const_reverse_iterator rbegin() const { return keys_.rbegin(); }
  110. constexpr const_reverse_iterator crbegin() const { return keys_.crbegin(); }
  111. constexpr const_reverse_iterator rend() const { return keys_.rend(); }
  112. constexpr const_reverse_iterator crend() const { return keys_.crend(); }
  113. /* comparison */
  114. constexpr bool operator==(set const& rhs) const { return bits::equal(begin(), end(), rhs.begin()); }
  115. constexpr bool operator!=(set const& rhs) const { return !(*this == rhs); }
  116. constexpr bool operator<(set const& rhs) const { return bits::lexicographical_compare(begin(), end(), rhs.begin(), rhs.end()); }
  117. constexpr bool operator<=(set const& rhs) const { return (*this < rhs) || (*this == rhs); }
  118. constexpr bool operator>(set const& rhs) const { return bits::lexicographical_compare(rhs.begin(), rhs.end(), begin(), end()); }
  119. constexpr bool operator>=(set const& rhs) const { return (*this > rhs) || (*this == rhs); }
  120. };
  121. template <class Key, class Compare> class set<Key, 0, Compare> {
  122. using container_type = bits::carray<Key, 0>; // just for the type definitions
  123. Compare less_than_;
  124. public:
  125. /* container typedefs*/
  126. using key_type = Key;
  127. using value_type = Key;
  128. using size_type = typename container_type::size_type;
  129. using difference_type = typename container_type::size_type;
  130. using key_compare = Compare;
  131. using value_compare = Compare;
  132. using reference = typename container_type::const_reference;
  133. using const_reference = reference;
  134. using pointer = typename container_type::const_pointer;
  135. using const_pointer = pointer;
  136. using iterator = pointer;
  137. using reverse_iterator = pointer;
  138. using const_iterator = const_pointer;
  139. using const_reverse_iterator = const_pointer;
  140. public:
  141. /* constructors */
  142. constexpr set(const set &other) = default;
  143. constexpr set(bits::carray<Key, 0>, Compare const &) {}
  144. explicit constexpr set(bits::carray<Key, 0>) {}
  145. constexpr set(std::initializer_list<Key>, Compare const &comp)
  146. : less_than_{comp} {}
  147. constexpr set(std::initializer_list<Key> keys) : set{keys, Compare{}} {}
  148. /* capacity */
  149. constexpr bool empty() const { return true; }
  150. constexpr size_type size() const { return 0; }
  151. constexpr size_type max_size() const { return 0; }
  152. /* lookup */
  153. constexpr std::size_t count(Key const &) const { return 0; }
  154. constexpr const_iterator find(Key const &) const { return end(); }
  155. constexpr std::pair<const_iterator, const_iterator>
  156. equal_range(Key const &) const { return {end(), end()}; }
  157. constexpr const_iterator lower_bound(Key const &) const { return end(); }
  158. constexpr const_iterator upper_bound(Key const &) const { return end(); }
  159. /* observers */
  160. constexpr key_compare key_comp() const { return less_than_; }
  161. constexpr key_compare value_comp() const { return less_than_; }
  162. /* iterators */
  163. constexpr const_iterator begin() const { return nullptr; }
  164. constexpr const_iterator cbegin() const { return nullptr; }
  165. constexpr const_iterator end() const { return nullptr; }
  166. constexpr const_iterator cend() const { return nullptr; }
  167. constexpr const_reverse_iterator rbegin() const { return nullptr; }
  168. constexpr const_reverse_iterator crbegin() const { return nullptr; }
  169. constexpr const_reverse_iterator rend() const { return nullptr; }
  170. constexpr const_reverse_iterator crend() const { return nullptr; }
  171. };
  172. template <typename T>
  173. constexpr auto make_set(bits::ignored_arg = {}/* for consistency with the initializer below for N = 0*/) {
  174. return set<T, 0>{};
  175. }
  176. template <typename T, std::size_t N>
  177. constexpr auto make_set(const T (&args)[N]) {
  178. return set<T, N>(args);
  179. }
  180. } // namespace frozen
  181. #endif