56 = (std::numeric_limits<T>::digits + std::numeric_limits<T>::is_signed
57 < std::numeric_limits<std::uintmax_t>::digits)
58 ?
static_cast<std::uintmax_t
>(1)
60 + std::numeric_limits<T>::is_signed)
62 static_assert(range_of<unsigned char> == 1u <<
to_unsigned(CHAR_BIT),
"");
63 static_assert(range_of<signed char> == 1u <<
to_unsigned(CHAR_BIT),
"");
65 template <
typename T,
bool
66 = std::is_trivially_default_constructible<T>::value and
67 std::is_trivially_destructible<T>::value>
68 struct alignas(T)
storage_for :
private std::array<byte, sizeof(T)> {
71 enable_if_t<std::is_constructible<T, Args&&...>::value,
int> = 0>
73 std::is_nothrow_constructible<T, Args&&...>::value) -> T& {
74 return *
new (this->data()) T(std::forward<Args>(args)...);
85 constexpr auto destroy() noexcept ->
void {
get()->~T(); }
88# define LAUNDER(x) std::launder(x)
90# define LAUNDER(x) (x)
93 return LAUNDER(
reinterpret_cast<T*
>(this->data()));
96 return LAUNDER(
reinterpret_cast<const T*
>(this->data()));
100 template <
typename T>
108 enable_if_t<std::is_constructible<T, Args&&...>::value,
int> = 0>
110 std::is_nothrow_constructible<T, Args&&...>::value) -> T& {
111 return *
new (&t) T(std::forward<Args>(args)...);
124template <
typename Key,
typename T,
typename allocator =
void>
140 constexpr static std::ptrdiff_t key_range{detail_direct_map::range_of<Key>};
144 = std::pair<std::bitset<key_range>, std::array<storage_type, key_range>>;
146 template <
typename V>
152 constexpr iter(
decltype(storage) s, std::ptrdiff_t p)
160 : iter(nullptr,
max()) {}
162 using value_type =
typename direct_map::value_type;
163 using difference_type =
typename direct_map::difference_type;
164 using reference = copy_const_t<V, value_type>&;
165 using pointer = copy_const_t<V, value_type>*;
166 using iterator_category = std::bidirectional_iterator_tag;
169 return *storage->second[uindex(pos)].get();
171 KBLIB_NODISCARD constexpr auto operator->() const noexcept -> pointer {
172 return storage->second[uindex(pos)].get();
175 constexpr auto operator++() noexcept -> iter& {
182 for (
auto i :
range(++pos, index(
max()))) {
183 if (storage->first.test(uindex(i))) {
191 constexpr auto operator++(
int)
noexcept -> iter {
197 constexpr auto operator--() noexcept -> iter& {
198 for (
auto i :
range(pos - 1, index(
min()), -1)) {
199 if (storage->first.test(uindex(i))) {
207 constexpr auto operator--(
int)
noexcept -> iter {
213 KBLIB_NODISCARD friend constexpr auto operator==(iter l, iter r)
noexcept
215 return l.storage == r.storage and l.pos == r.pos;
217 KBLIB_NODISCARD friend constexpr auto operator!=(iter l, iter r)
noexcept
222 KBLIB_NODISCARD friend constexpr auto operator op(iter l, \
223 iter r) noexcept->bool { \
224 assert(l.storage == r.storage); \
225 return l.pos op r.pos; \
233 constexpr auto swap(iter& other)
noexcept ->
void {
247 template <typename InputIt>
252 for (
auto v :
indirect(first, last)) {
253 construct(v.first, v.second);
260 , _size(other._size) {
261 if (not other.
empty()) {
263 storage->first = other.storage->first;
266 do_construct(
k, other.
at(
k));
273 : storage(std::move(other.storage))
285 if (
this == &other) {
293 do_construct(
k, other.at(
k));
294 bitmap().set(index(
k));
301 constexpr auto operator=(std::initializer_list<value_type> init)
304 for (
auto it : init) {
305 construct(it->first, it->second);
312 return unsafe_at(key).get()->second;
314 throw std::out_of_range(
"direct_map: key out of range");
319 return std::move(unsafe_at(key).
get()->second);
321 throw std::out_of_range(
"direct_map: key out of range");
326 return unsafe_at(key).get()->second;
328 throw std::out_of_range(
"direct_map: key out of range");
333 return std::move(unsafe_at(key).
get()->second);
335 throw std::out_of_range(
"direct_map: key out of range");
340 std::is_nothrow_default_constructible<T>::value) {
341 return try_emplace(key).first->second;
345 return {storage.get(), cbegin().pos};
348 return {storage.get(), cbegin().pos};
353 return {storage.get(),
min()};
363 return {storage.get(),
max()};
366 return {storage.get(),
max()};
369 return {storage.get(),
max()};
373 return std::make_reverse_iterator(end());
376 return std::make_reverse_iterator(end());
379 return std::make_reverse_iterator(cend());
383 return std::make_reverse_iterator(begin());
386 return std::make_reverse_iterator(begin());
389 return std::make_reverse_iterator(cbegin());
407 constexpr auto clear() noexcept ->
void {
412 auto j =
static_cast<Key
>(i);
414 unsafe_at(j).destroy();
423 construct(value.first, value.second);
424 return {{storage.get(), index(value.first)},
true};
426 return {{storage.get(), index(value.first)},
false};
429 template <
typename U>
432 std::pair<iterator, bool>> {
434 construct(value.first, std::forward<U>(value.second));
435 return {{storage.get(), index(value.first)},
true};
437 return {{storage.get(), index(value.first)},
false};
442 construct(value.first, std::move(value.second));
443 return {{storage.get(), index(value.first)},
true};
445 return {{storage.get(), index(value.first)},
false};
449 template <
typename U>
451 -> std::pair<iterator, bool> {
453 construct(key, std::forward<U>(value));
454 return {{storage.get(), index(key)},
true};
456 *unsafe_at(key).get() = std::forward<U>(value);
457 return {{storage.get(), index(key)},
false};
460 template <
typename... Args>
462 -> std::pair<iterator, bool> {
464 construct(key, std::forward<Args>(args)...);
465 return {{storage.get(), index(key)},
true};
467 return {{storage.get(), index(key)},
false};
473 bitmap().reset(pos.pos);
474 unsafe_at(to_key(pos.pos)).destroy();
480 bitmap().reset(pos.pos);
481 unsafe_at(to_key(pos.pos)).destroy();
487 for (
auto i :
range(first.pos, last.pos)) {
490 unsafe_at(to_key(i)).destroy();
497 constexpr auto erase(Key key)
noexcept -> std::size_t {
499 bitmap().reset(index(key));
500 unsafe_at(key).destroy();
510 swap(storage, other.storage);
511 swap(_size, other._size);
515 return storage and bitmap().test(uindex(key));
530 -> std::pair<iterator, iterator> {
531 return {lower_bound(key), upper_bound(key)};
534 -> std::pair<const_iterator, const_iterator> {
535 return {lower_bound(key), upper_bound(key)};
542 return ++
iterator{storage.get(), index(key)};
550 return ++
iterator{storage.get(), index(key)};
556 auto l = lower_bound(key);
557 if (l.pos == index(key)) {
567 auto l = lower_bound(key);
568 if (l.pos == index(key)) {
585 const direct_map& r)
noexcept(
noexcept(std::declval<T&>()
586 == std::declval<T&>())) ->
bool {
587 if (l.size() != r.size()) {
591 if (l.contains(i) != r.contains(i)) {
593 }
else if (l.contains(i)) {
594 if (l.at(i) != r.at(i)) {
604 const direct_map& r)
noexcept(
noexcept(std::declval<T&>()
605 == std::declval<T&>())) ->
bool {
611 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
612 std::declval<T&>())) ->
bool {
618 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
619 std::declval<T&>())) ->
bool {
624 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
625 std::declval<T&>())) ->
bool {
630 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
631 std::declval<T&>())) ->
bool {
650 return storage->first;
654 return storage->first;
658 return storage->second[uindex(key)];
660 KBLIB_NODISCARD constexpr auto unsafe_at(Key key) && -> storage_type&& {
661 return storage->second[uindex(key)];
665 return storage->second[uindex(key)];
669 return storage->second[uindex(key)];
672 auto allocate() ->
void {
678 template <
typename... Args>
679 constexpr void construct(Key key, Args&&... args)
noexcept(
680 std::is_nothrow_constructible<value_type, Args&&...>::value) {
682 if (not storage->first.test(uindex(key))) {
683 do_construct(key, std::forward<Args>(args)...);
685 storage->first.set(uindex(key));
690 template <
typename... Args>
691 constexpr void do_construct(Key key, Args&&... args)
noexcept(
692 std::is_nothrow_constructible<value_type, Args&&...>::value) {
693 storage->second[uindex(key)].construct(
694 std::piecewise_construct, std::forward_as_tuple(key),
695 std::forward_as_tuple(std::forward<Args>(args)...));
704template <
typename Key,
typename T>
720 constexpr static std::ptrdiff_t key_range{detail_direct_map::range_of<Key>};
723 template <
typename V>
729 constexpr iter(
decltype(
map) s, std::ptrdiff_t p)
737 : iter(nullptr,
max()) {}
739 using value_type =
typename direct_map::value_type;
740 using difference_type =
typename direct_map::difference_type;
741 using reference = copy_const_t<V, value_type>&;
742 using pointer = copy_const_t<V, value_type>*;
743 using iterator_category = std::bidirectional_iterator_tag;
746 return *
map->elems[uindex(pos)].get();
749 return map->elems[uindex(pos)].get();
752 constexpr auto operator++() -> iter& {
759 for (
auto i :
range(++pos, index(
max()))) {
760 if (
map->active_elems.test(uindex(i))) {
768 constexpr auto operator++(
int) -> iter {
774 constexpr auto operator--() -> iter& {
775 for (
auto i :
range(pos - 1, index(
min()), -1)) {
776 if (
map->active_elems.test(uindex(i))) {
784 constexpr auto operator--(
int) -> iter {
790 KBLIB_NODISCARD friend constexpr auto operator==(iter l, iter r)
noexcept
792 return l.map == r.map and l.pos == r.pos;
794 KBLIB_NODISCARD friend constexpr auto operator!=(iter l, iter r)
noexcept
800 KBLIB_NODISCARD friend constexpr auto operator op(iter l, \
801 iter r) noexcept->bool { \
802 assert(l.map == r.map); \
803 return l.pos op r.pos; \
811 constexpr auto swap(iter& other)
noexcept ->
void {
825 template <typename InputIt>
827 for (
auto&& v :
indirect(first, last)) {
828 construct(std::forward<
decltype(v)>(v).first,
829 std::forward<
decltype(v)>(v).second);
834 : active_elems{other.active_elems}
835 , _size(other._size) {
838 do_construct(
k, other.unsafe_at(
k).get()->second);
839 bitmap().set(uindex(
k));
845 std::is_nothrow_move_constructible<value_type>::value)
846 : active_elems{other.active_elems}
847 , _size(other._size) {
850 do_construct(
k, std::move(other.unsafe_at(
k).get()->second));
851 bitmap().set(uindex(
k));
864 if (
this == &other) {
868 active_elems = other.active_elems;
872 do_construct(
k, other.unsafe_at(
k).get()->second);
873 bitmap().set(uindex(
k));
879 std::is_nothrow_move_constructible<T>::value) ->
direct_map& {
880 if (
this == &other) {
883 active_elems = other.active_elems;
887 do_construct(
k, std::move(other.unsafe_at(
k).get()->second));
888 bitmap().set(uindex(
k));
893 constexpr auto operator=(std::initializer_list<value_type> init)
896 for (
auto it : init) {
897 construct(it->first, it->second);
904 return unsafe_at(key).get()->second;
906 throw std::out_of_range(
"direct_map: key out of range");
911 return std::move(unsafe_at(key).
get()->second);
913 throw std::out_of_range(
"direct_map: key out of range");
918 return unsafe_at(key).get()->second;
920 throw std::out_of_range(
"direct_map: key out of range");
925 return std::move(unsafe_at(key).
get()->second);
927 throw std::out_of_range(
"direct_map: key out of range");
932 std::is_nothrow_default_constructible<T>::value) {
933 return try_emplace(key).first->second;
937 return {
this, cbegin().pos};
940 return {
this, cbegin().pos};
945 return {
this,
min()};
955 return {
this,
max()};
958 return {
this,
max()};
961 return {
this,
max()};
965 return std::make_reverse_iterator(end());
969 return std::make_reverse_iterator(end());
973 return std::make_reverse_iterator(crend());
977 return std::make_reverse_iterator(begin());
981 return std::make_reverse_iterator(begin());
985 return std::make_reverse_iterator(cbegin());
1003 constexpr auto clear() noexcept ->
void {
1005 auto j =
static_cast<Key
>(i);
1007 unsafe_at(j).destroy();
1015 construct(value.first, value.second);
1016 return {{
this, index(value.first)},
true};
1018 return {{
this, index(value.first)},
false};
1021 template <
typename U>
1024 std::pair<iterator, bool>> {
1026 construct(value.first, std::forward<U>(value.second));
1027 return {{
this, index(value.first)},
true};
1029 return {{
this, index(value.first)},
false};
1034 construct(value.first, std::move(value.second));
1035 return {{
this, index(value.first)},
true};
1037 return {{
this, index(value.first)},
false};
1041 template <
typename U>
1043 -> std::pair<iterator, bool> {
1045 construct(key, std::forward<U>(value));
1046 return {{
this, index(key)},
true};
1048 *unsafe_at(key).get() = std::forward<U>(value);
1049 return {{
this, index(key)},
false};
1052 template <
typename... Args>
1054 -> std::pair<iterator, bool> {
1056 construct(key, std::forward<Args>(args)...);
1057 return {{
this, index(key)},
true};
1059 return {{
this, index(key)},
false};
1065 destroy(to_key(pos.pos));
1070 destroy(to_key(pos.pos));
1075 for (
auto i :
range(first.pos, last.pos)) {
1083 constexpr auto erase(Key key)
noexcept -> std::size_t {
1093 std::is_nothrow_move_constructible<value_type>::value and
1098 if (other.contains(
k)) {
1100 other.unsafe_at(
k).get()->second);
1102 other.construct(
k, std::move(unsafe_at(
k).
get()->second));
1105 }
else if (other.contains(
k)) {
1106 construct(
k, std::move(other.unsafe_at(
k).get()->second));
1113 swap(active_elems, other.active_elems);
1114 swap(_size, other._size);
1118 return bitmap().test(uindex(key));
1133 -> std::pair<iterator, iterator> {
1134 return {lower_bound(key), upper_bound(key)};
1137 -> std::pair<const_iterator, const_iterator> {
1138 return {lower_bound(key), upper_bound(key)};
1145 return ++
iterator{
this, index(key)};
1153 return ++
iterator{
this, index(key)};
1159 auto l = lower_bound(key);
1160 if (l.pos == index(key)) {
1170 auto l = lower_bound(key);
1171 if (l.pos == index(key)) {
1188 const direct_map& r)
noexcept(
noexcept(std::declval<T&>()
1189 == std::declval<T&>())) ->
bool {
1190 if (l.size() != r.size()) {
1194 if (l.contains(i) != r.contains(i)) {
1196 }
else if (l.contains(i)) {
1197 if (l.at(i) != r.at(i)) {
1207 const direct_map& r)
noexcept(
noexcept(std::declval<T&>()
1208 == std::declval<T&>())) ->
bool {
1209 return not (l == r);
1214 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
1215 std::declval<T&>())) ->
bool {
1221 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
1222 std::declval<T&>())) ->
bool {
1227 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
1228 std::declval<T&>())) ->
bool {
1233 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
1234 std::declval<T&>())) ->
bool {
1253 return active_elems;
1256 -> const
std::bitset<key_range>& {
1257 return active_elems;
1260 KBLIB_NODISCARD constexpr auto unsafe_at(Key key) & -> storage_type& {
1261 return elems[uindex(key)];
1263 KBLIB_NODISCARD constexpr auto unsafe_at(Key key) && -> storage_type&& {
1264 return elems[uindex(key)];
1268 return elems[uindex(key)];
1272 return elems[uindex(key)];
1275 template <
typename... Args>
1276 constexpr auto construct(Key key, Args&&... args)
noexcept(
1277 std::is_nothrow_constructible<value_type, Args&&...>::value) ->
void {
1278 if (not active_elems.test(uindex(key))) {
1279 do_construct(key, std::forward<Args>(args)...);
1281 active_elems.set(uindex(key));
1286 template <
typename... Args>
1287 constexpr auto do_construct(Key key, Args&&... args)
noexcept(
1288 std::is_nothrow_constructible<value_type, Args&&...>::value) ->
void {
1289 elems[uindex(key)].construct(
1290 std::piecewise_construct, std::forward_as_tuple(key),
1291 std::forward_as_tuple(std::forward<Args>(args)...));
1294 auto destroy(Key key) ->
void {
1297 bitmap().reset(uindex(key));
1298 unsafe_at(key).destroy();
1304 std::bitset<key_range> active_elems;
1305 std::array<storage_type, key_range> elems;
1307 std::size_t _size{};
KBLIB_NODISCARD constexpr auto count(Key key) const noexcept -> std::size_t
KBLIB_NODISCARD constexpr auto equal_range(Key key) &noexcept -> std::pair< iterator, iterator >
KBLIB_NODISCARD constexpr auto end() &noexcept -> iterator
constexpr auto erase(iterator first, iterator last) noexcept -> iterator
KBLIB_NODISCARD static constexpr auto max() noexcept -> Key
KBLIB_NODISCARD constexpr auto contains(Key key) const noexcept -> bool
KBLIB_NODISCARD constexpr auto size() const &noexcept -> std::size_t
KBLIB_NODISCARD constexpr auto at(Key key) const &-> const T &
KBLIB_NODISCARD constexpr auto ssize() const &noexcept -> std::ptrdiff_t
constexpr auto insert_or_assign(Key key, U &&value) -> std::pair< iterator, bool >
constexpr auto insert(U &&value) -> return_assert_t< std::is_constructible< value_type, U && >::value, std::pair< iterator, bool > >
KBLIB_NODISCARD constexpr auto upper_bound(Key key) &noexcept -> iterator
KBLIB_NODISCARD static constexpr auto min() noexcept -> Key
constexpr auto insert(const value_type &value) -> std::pair< iterator, bool >
KBLIB_NODISCARD static constexpr auto index(Key key) noexcept -> std::ptrdiff_t
KBLIB_NODISCARD constexpr auto rbegin() const &noexcept -> const_reverse_iterator
iter< const value_type > const_iterator
KBLIB_NODISCARD constexpr auto upper_bound(Key key) const &noexcept -> const_iterator
KBLIB_NODISCARD friend constexpr auto operator==(const direct_map &l, const direct_map &r) noexcept(noexcept(std::declval< T & >()==std::declval< T & >())) -> bool
constexpr auto erase(iterator pos) noexcept -> iterator
iter< value_type > iterator
KBLIB_NODISCARD constexpr auto find(Key key) &noexcept -> iterator
KBLIB_NODISCARD constexpr auto find(Key key) const &noexcept -> const_iterator
constexpr auto clear() noexcept -> void
const value_type * const_pointer
KBLIB_NODISCARD constexpr auto cbegin() const &noexcept -> const_iterator
KBLIB_NODISCARD friend constexpr auto operator>=(const direct_map &l, const direct_map &r) noexcept(noexcept(std::declval< T & >(), std::declval< T & >())) -> bool
std::reverse_iterator< const_iterator > const_reverse_iterator
constexpr auto operator=(direct_map &&other) noexcept(std::is_nothrow_move_constructible< T >::value) -> direct_map &
KBLIB_NODISCARD constexpr auto rbegin() &noexcept -> reverse_iterator
KBLIB_NODISCARD constexpr auto at(Key key) &&-> T &&
KBLIB_NODISCARD constexpr auto crend() const &noexcept -> const_reverse_iterator
constexpr direct_map(const direct_map &other)
constexpr direct_map(direct_map &&other) noexcept(std::is_nothrow_move_constructible< value_type >::value)
KBLIB_NODISCARD constexpr T & operator[](Key key) noexcept(std::is_nothrow_default_constructible< T >::value)
KBLIB_NODISCARD constexpr auto at(Key key) &-> T &
KBLIB_NODISCARD constexpr auto at(Key key) const &&-> const T &&
std::reverse_iterator< iterator > reverse_iterator
constexpr direct_map() noexcept=default
constexpr auto erase(Key key) noexcept -> std::size_t
std::ptrdiff_t difference_type
KBLIB_NODISCARD friend constexpr auto operator>(const direct_map &l, const direct_map &r) noexcept(noexcept(std::declval< T & >(), std::declval< T & >())) -> bool
KBLIB_NODISCARD constexpr auto begin() const &noexcept -> const_iterator
KBLIB_NODISCARD constexpr auto end() const &noexcept -> const_iterator
constexpr direct_map(std::initializer_list< value_type > init)
constexpr auto swap(direct_map &other) noexcept(std::is_nothrow_move_constructible< value_type >::value and fakestd::is_nothrow_swappable< T >::value) -> void
KBLIB_NODISCARD constexpr auto cend() const &noexcept -> const_iterator
KBLIB_NODISCARD constexpr auto rend() const &noexcept -> const_reverse_iterator
KBLIB_NODISCARD static constexpr auto max_size() noexcept -> std::size_t
KBLIB_NODISCARD constexpr auto lower_bound(Key key) const &noexcept -> const_iterator
KBLIB_CXX20(constexpr) ~direct_map()
KBLIB_NODISCARD friend constexpr auto operator<=(const direct_map &l, const direct_map &r) noexcept(noexcept(std::declval< T & >(), std::declval< T & >())) -> bool
KBLIB_NODISCARD static constexpr auto uindex(Key key) noexcept -> std::size_t
constexpr auto insert(value_type &&value) -> std::pair< iterator, bool >
KBLIB_NODISCARD constexpr auto empty() const &noexcept -> bool
KBLIB_NODISCARD constexpr auto lower_bound(Key key) &noexcept -> iterator
KBLIB_NODISCARD constexpr auto rend() &noexcept -> reverse_iterator
constexpr auto erase(const_iterator pos) noexcept -> iterator
KBLIB_NODISCARD friend constexpr auto operator!=(const direct_map &l, const direct_map &r) noexcept(noexcept(std::declval< T & >()==std::declval< T & >())) -> bool
constexpr auto operator=(const direct_map &other) -> direct_map &
constexpr auto operator=(std::initializer_list< value_type > init) -> direct_map &
KBLIB_NODISCARD constexpr auto begin() &noexcept -> iterator
const value_type & const_reference
KBLIB_NODISCARD friend constexpr auto operator<(const direct_map &l, const direct_map &r) noexcept(noexcept(std::declval< T & >(), std::declval< T & >())) -> bool
std::pair< const Key, T > value_type
KBLIB_NODISCARD static constexpr auto to_key(std::ptrdiff_t i) noexcept -> Key
KBLIB_NODISCARD constexpr auto equal_range(Key key) const &noexcept -> std::pair< const_iterator, const_iterator >
constexpr auto try_emplace(Key key, Args &&... args) -> std::pair< iterator, bool >
KBLIB_NODISCARD constexpr auto crbegin() const &noexcept -> const_reverse_iterator
iter< value_type > iterator
KBLIB_NODISCARD constexpr auto rend() const &noexcept -> auto
constexpr auto insert(const value_type &value) -> std::pair< iterator, bool >
KBLIB_NODISCARD constexpr auto begin() const &noexcept -> const_iterator
constexpr auto insert_or_assign(Key key, U &&value) -> std::pair< iterator, bool >
constexpr auto clear() noexcept -> void
constexpr direct_map(const direct_map &other)
std::reverse_iterator< const_iterator > const_reverse_iterator
KBLIB_NODISCARD constexpr auto size() const &noexcept -> std::size_t
KBLIB_NODISCARD constexpr auto crbegin() const &noexcept -> auto
constexpr auto erase(iterator pos) noexcept -> iterator
KBLIB_NODISCARD constexpr auto at(Key key) const &-> const T &
KBLIB_NODISCARD constexpr auto rbegin() const &noexcept -> auto
constexpr auto operator=(const direct_map &other) -> direct_map &
KBLIB_NODISCARD constexpr auto find(Key key) &noexcept -> iterator
constexpr auto erase(const_iterator pos) noexcept -> iterator
KBLIB_NODISCARD constexpr auto upper_bound(Key key) const &noexcept -> const_iterator
KBLIB_NODISCARD constexpr auto rend() &noexcept -> auto
KBLIB_NODISCARD friend constexpr auto operator==(const direct_map &l, const direct_map &r) noexcept(noexcept(std::declval< T & >()==std::declval< T & >())) -> bool
KBLIB_NODISCARD constexpr auto rbegin() &noexcept -> auto
KBLIB_NODISCARD constexpr auto equal_range(Key key) const &noexcept -> std::pair< const_iterator, const_iterator >
KBLIB_NODISCARD constexpr auto end() const &noexcept -> const_iterator
constexpr auto erase(iterator first, iterator last) noexcept -> iterator
KBLIB_NODISCARD friend constexpr auto operator>=(const direct_map &l, const direct_map &r) noexcept(noexcept(std::declval< T & >(), std::declval< T & >())) -> bool
KBLIB_NODISCARD constexpr auto contains(Key key) const noexcept -> bool
KBLIB_NODISCARD constexpr auto begin() &noexcept -> iterator
KBLIB_NODISCARD static constexpr auto max_size() noexcept -> std::size_t
KBLIB_NODISCARD constexpr auto ssize() const &noexcept -> std::ptrdiff_t
KBLIB_NODISCARD constexpr auto cbegin() const &noexcept -> const_iterator
constexpr auto try_emplace(Key key, Args &&... args) -> std::pair< iterator, bool >
KBLIB_NODISCARD static constexpr auto uindex(Key key) noexcept -> std::size_t
KBLIB_NODISCARD static constexpr auto max() noexcept -> Key
constexpr auto swap(direct_map &other) noexcept -> void
KBLIB_NODISCARD constexpr auto empty() const &noexcept -> bool
KBLIB_NODISCARD friend constexpr auto operator>(const direct_map &l, const direct_map &r) noexcept(noexcept(std::declval< T & >(), std::declval< T & >())) -> bool
KBLIB_NODISCARD constexpr auto at(Key key) &&-> T &&
KBLIB_NODISCARD constexpr auto at(Key key) const &&-> const T &&
KBLIB_NODISCARD constexpr auto end() &noexcept -> iterator
KBLIB_NODISCARD constexpr auto equal_range(Key key) &noexcept -> std::pair< iterator, iterator >
std::ptrdiff_t difference_type
constexpr direct_map(std::initializer_list< value_type > init)
std::pair< const Key, T > value_type
KBLIB_NODISCARD constexpr auto upper_bound(Key key) &noexcept -> iterator
const value_type * const_pointer
KBLIB_NODISCARD static constexpr auto min() noexcept -> Key
KBLIB_CXX20(constexpr) ~direct_map()
KBLIB_NODISCARD friend constexpr auto operator<=(const direct_map &l, const direct_map &r) noexcept(noexcept(std::declval< T & >(), std::declval< T & >())) -> bool
constexpr auto operator=(direct_map &&other) noexcept -> direct_map &=default
constexpr auto operator=(std::initializer_list< value_type > init) -> direct_map &
KBLIB_NODISCARD constexpr auto cend() const &noexcept -> const_iterator
std::reverse_iterator< iterator > reverse_iterator
KBLIB_NODISCARD constexpr auto crend() const &noexcept -> auto
KBLIB_NODISCARD constexpr auto find(Key key) const &noexcept -> const_iterator
constexpr auto erase(Key key) noexcept -> std::size_t
KBLIB_NODISCARD constexpr auto at(Key key) &-> T &
KBLIB_NODISCARD friend constexpr auto operator!=(const direct_map &l, const direct_map &r) noexcept(noexcept(std::declval< T & >()==std::declval< T & >())) -> bool
KBLIB_NODISCARD constexpr auto lower_bound(Key key) &noexcept -> iterator
constexpr auto insert(value_type &&value) -> std::pair< iterator, bool >
KBLIB_NODISCARD constexpr T & operator[](Key key) noexcept(std::is_nothrow_default_constructible< T >::value)
iter< const value_type > const_iterator
KBLIB_NODISCARD friend constexpr auto operator<(const direct_map &l, const direct_map &r) noexcept(noexcept(std::declval< T & >(), std::declval< T & >())) -> bool
KBLIB_NODISCARD static constexpr auto index(Key key) noexcept -> std::ptrdiff_t
constexpr auto insert(U &&value) -> enable_if_t< std::is_constructible< value_type, U && >::value, std::pair< iterator, bool > >
constexpr direct_map() noexcept=default
KBLIB_NODISCARD constexpr auto lower_bound(Key key) const &noexcept -> const_iterator
constexpr direct_map(direct_map &&other) noexcept
KBLIB_NODISCARD constexpr auto count(Key key) const noexcept -> std::size_t
KBLIB_NODISCARD static constexpr auto to_key(std::ptrdiff_t i) noexcept -> Key
const value_type & const_reference
This header provides some features of C++17 <type_traits> and other headers for C++14,...
This file provides some iterators, ranges, iterator/range adapters, and operations that can be perfor...
KBLIB_CONSTANT auto range_of
constexpr struct kblib::nums::min_t min
constexpr struct kblib::nums::max_t max
constexpr auto contains(InputIt begin, InputIt end, const Value &val) noexcept(noexcept(*begin==val)) -> enable_if_t< is_input_iterator< InputIt >::value, bool >
Determine if a range contains a value.
constexpr auto exchange(T &obj, U &&new_value) -> T
auto map(F f, T &&... t) noexcept(noexcept(std::tuple{ kblib::apply(f, std::forward< T >(t))...})) -> enable_if_t< not any_void< decltype(kblib::apply(f, std::forward< T >(t)))... >, decltype(std::tuple{kblib::apply(f, std::forward< T >(t))...})>
constexpr auto to_signed(I x) -> std::make_signed_t< I >
Cast integral argument to corresponding signed type.
typename std::enable_if< B, T >::type enable_if_t
constexpr auto range(Value min, Value max, Delta step=0) -> range_t< Value, Delta >
Constructs a range from beginning, end, and step amount. The range is half-open, that is min is in th...
constexpr auto indirect(Iter1 begin, Iter2 end) noexcept(noexcept(indirect_range< Iter1, Iter2 >{begin, end})) -> indirect_range< Iter1, Iter2 >
Create a range from an iterator pair. Primarily useful for range-for loops.
auto get(punner< Types... > &p) noexcept -> decltype(auto)
constexpr auto find(ForwardIt begin, EndIt end, const Elem &value) noexcept(noexcept(*begin==value)) -> ForwardIt
Finds a value in range [begin, end). If not found, returns end. It also allows for a sentinel end ite...
typename return_assert< V, T >::type return_assert_t
constexpr auto operator*(construct_type l, bool r) noexcept -> construct_type
constexpr auto lexicographical_compare(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2) -> bool
constexpr struct kblib::in_place_agg_t in_place_agg
typename copy_const< C, V >::type copy_const_t
constexpr auto to_unsigned(I x) -> std::make_unsigned_t< I >
Cast integral argument to corresponding unsigned type.
constexpr auto destroy() noexcept -> void
KBLIB_NODISCARD constexpr auto get() &noexcept -> T *
KBLIB_NODISCARD constexpr auto get() const &noexcept -> const T *
constexpr auto construct(Args &&... args) noexcept(std::is_nothrow_constructible< T, Args &&... >::value) -> T &
constexpr auto construct(Args &&... args) noexcept(std::is_nothrow_constructible< T, Args &&... >::value) -> T &
KBLIB_NODISCARD constexpr auto get() &noexcept -> T *
auto operator=(storage_for &&) -> storage_for &=delete
storage_for(storage_for &&)=delete
auto operator=(const storage_for &) -> storage_for &=delete
KBLIB_NODISCARD constexpr auto get() const &noexcept -> const T *
storage_for(const storage_for &)=delete
constexpr auto destroy() noexcept -> void
Provides macros and basic templates used by the rest of kblib.
#define KBLIB_NODISCARD
This internal macro is used to provide a fallback for [[nodiscard]] in C++14.