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>
156 using iterator_category = std::bidirectional_iterator_tag;
161 KBLIB_NODISCARD constexpr auto operator->() const noexcept -> pointer {
165 constexpr auto operator++() noexcept -> iter& {
166 if (pos == key_range) {
172 for (
auto i :
range(++pos, key_range)) {
181 constexpr auto operator++(
int)
noexcept -> iter {
187 constexpr auto operator--() noexcept -> iter& {
188 for (
auto i :
range(pos - 1, std::ptrdiff_t(-1))) {
195 __builtin_unreachable();
197 constexpr auto operator--(
int)
noexcept -> iter {
203 KBLIB_NODISCARD friend constexpr auto operator==(iter l, iter r)
noexcept
205 return l.storage == r.storage and l.pos == r.pos;
207 KBLIB_NODISCARD friend constexpr auto operator!=(iter l, iter r)
noexcept
212 KBLIB_NODISCARD friend constexpr auto operator op(iter l, \
213 iter r) noexcept->bool { \
214 assert(l.storage == r.storage); \
215 return l.pos op r.pos; \
223 constexpr auto swap(iter& other)
noexcept ->
void {
237 template <typename InputIt>
240 for (
auto v :
indirect(first, last)) {
241 construct(v.first, v.second);
247 , _size(other._size) {
250 do_construct(
k, other.
at(
k));
257 : storage(std::move(other.storage))
269 if (
this == &other) {
276 do_construct(
k, other.at(
k));
278 bitmap().set(index(
k));
285 constexpr auto operator=(std::initializer_list<value_type> init)
288 for (
auto it : init) {
289 construct(it->first, it->second);
296 return unsafe_at(key).get()->second;
298 throw std::out_of_range(
"direct_map: key out of range");
303 return std::move(unsafe_at(key).
get()->second);
305 throw std::out_of_range(
"direct_map: key out of range");
310 return unsafe_at(key).get()->second;
312 throw std::out_of_range(
"direct_map: key out of range");
317 return std::move(unsafe_at(key).
get()->second);
319 throw std::out_of_range(
"direct_map: key out of range");
324 std::is_nothrow_default_constructible<T>::value) {
325 return try_emplace(key).first->second;
329 return {storage.get(), cbegin().pos};
332 return {storage.get(), cbegin().pos};
337 return {storage.get(), 0};
342 return {storage.get(), key_range};
347 return {storage.get(), key_range};
350 return {storage.get(), key_range};
353 return {storage.get(), key_range};
357 return std::make_reverse_iterator(end());
360 return std::make_reverse_iterator(end());
363 return std::make_reverse_iterator(cend());
367 return std::make_reverse_iterator(begin());
370 return std::make_reverse_iterator(begin());
373 return std::make_reverse_iterator(cbegin());
391 constexpr auto clear() noexcept ->
void {
393 auto j =
static_cast<Key
>(i);
395 unsafe_at(j).destroy();
404 construct(value.first, value.second);
405 return {{storage.get(), index(value.first)},
true};
407 return {{storage.get(), index(value.first)},
false};
410 template <
typename U>
413 std::pair<iterator, bool>> {
415 construct(value.first, std::forward<U>(value.second));
416 return {{storage.get(), index(value.first)},
true};
418 return {{storage.get(), index(value.first)},
false};
423 construct(value.first, std::move(value.second));
424 return {{storage.get(), index(value.first)},
true};
426 return {{storage.get(), index(value.first)},
false};
430 template <
typename U>
432 -> std::pair<iterator, bool> {
434 construct(key, std::forward<U>(value));
435 return {{storage.get(), index(key)},
true};
437 *unsafe_at(key).get() = std::forward<U>(value);
438 return {{storage.get(), index(key)},
false};
441 template <
typename... Args>
443 -> std::pair<iterator, bool> {
445 construct(key, std::forward<Args>(args)...);
446 return {{storage.get(), index(key)},
true};
448 return {{storage.get(), index(key)},
false};
453 bitmap().reset(pos.pos);
454 unsafe_at(to_key(pos.pos)).destroy();
459 bitmap().reset(pos.pos);
460 unsafe_at(to_key(pos.pos)).destroy();
466 for (
auto i :
range(first.pos, last.pos)) {
469 unsafe_at(to_key(i)).destroy();
476 constexpr auto erase(Key key)
noexcept -> std::size_t {
478 bitmap().reset(index(key));
479 unsafe_at(key).destroy();
489 swap(storage, other.storage);
490 swap(_size, other._size);
494 return storage and bitmap().test(uindex(key));
502 :
iterator{storage.get(), key_range};
507 :
iterator{storage.get(), key_range};
511 -> std::pair<iterator, iterator> {
512 return {lower_bound(key), upper_bound(key)};
515 -> std::pair<const_iterator, const_iterator> {
516 return {lower_bound(key), upper_bound(key)};
523 return ++
iterator{storage.get(), index(key)};
531 return ++
iterator{storage.get(), index(key)};
537 auto l = lower_bound(key);
538 if (l.pos == index(key)) {
548 auto l = lower_bound(key);
549 if (l.pos == index(key)) {
566 const direct_map& r)
noexcept(
noexcept(std::declval<T&>()
567 == std::declval<T&>())) ->
bool {
568 if (l.size() != r.size()) {
572 if (l.contains(i) != r.contains(i)) {
574 }
else if (l.contains(i)) {
575 if (l.at(i) != r.at(i)) {
585 const direct_map& r)
noexcept(
noexcept(std::declval<T&>()
586 == std::declval<T&>())) ->
bool {
592 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
593 std::declval<T&>())) ->
bool {
599 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
600 std::declval<T&>())) ->
bool {
605 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
606 std::declval<T&>())) ->
bool {
611 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
612 std::declval<T&>())) ->
bool {
631 return storage->first;
635 return storage->first;
639 return storage->second[uindex(key)];
641 KBLIB_NODISCARD constexpr auto unsafe_at(Key key) && -> storage_type&& {
642 return storage->second[uindex(key)];
646 return storage->second[uindex(key)];
650 return storage->second[uindex(key)];
653 auto allocate() ->
void {
659 template <
typename... Args>
660 constexpr void construct(Key key, Args&&... args)
noexcept(
661 std::is_nothrow_constructible<value_type, Args&&...>::value) {
663 if (not storage->first.test(uindex(key))) {
664 do_construct(key, std::forward<Args>(args)...);
666 storage->first.set(uindex(key));
671 template <
typename... Args>
672 constexpr void do_construct(Key key, Args&&... args)
noexcept(
673 std::is_nothrow_constructible<value_type, Args&&...>::value) {
674 storage->second[uindex(key)].construct(
675 std::piecewise_construct, std::forward_as_tuple(key),
676 std::forward_as_tuple(std::forward<Args>(args)...));
685template <
typename Key,
typename T>
701 constexpr static std::ptrdiff_t key_range{detail_direct_map::range_of<Key>};
704 template <
typename V>
714 using iterator_category = std::bidirectional_iterator_tag;
723 constexpr auto operator++() -> iter& {
724 if (pos == key_range) {
730 for (
auto i :
range(++pos, key_range)) {
739 constexpr auto operator++(
int) -> iter {
745 constexpr auto operator--() -> iter& {
746 for (
auto i :
range(pos - 1, std::ptrdiff_t(-1))) {
753 __builtin_unreachable();
755 constexpr auto operator--(
int) -> iter {
761 KBLIB_NODISCARD friend constexpr auto operator==(iter l, iter r)
noexcept
763 return l.map == r.map and l.pos == r.pos;
765 KBLIB_NODISCARD friend constexpr auto operator!=(iter l, iter r)
noexcept
771 KBLIB_NODISCARD friend constexpr auto operator op(iter l, \
772 iter r) noexcept->bool { \
773 assert(l.map == r.map); \
774 return l.pos op r.pos; \
782 constexpr auto swap(iter& other)
noexcept ->
void {
796 template <typename InputIt>
798 for (
auto&& v :
indirect(first, last)) {
799 construct(std::forward<
decltype(v)>(v).first,
800 std::forward<
decltype(v)>(v).second);
805 : active_elems{other.active_elems}
806 , _size(other._size) {
809 construct(
k, other.unsafe_at(
k).get()->second);
811 bitmap().set(uindex(
k));
817 std::is_nothrow_move_constructible<value_type>::value)
818 : active_elems{other.active_elems}
819 , _size(other._size) {
822 construct(
k, std::move(other.unsafe_at(
k).get()->second));
824 bitmap().set(uindex(
k));
837 if (
this == &other) {
841 active_elems = other.active_elems;
844 construct(
k, other.unsafe_at(
k).get()->second);
846 bitmap().set(uindex(
k));
852 std::is_nothrow_move_constructible<T>::value) ->
direct_map& {
853 if (
this == &other) {
856 active_elems = other.active_elems;
859 construct(
k, std::move(other.unsafe_at(
k).get()->second));
861 bitmap().set(uindex(
k));
866 constexpr auto operator=(std::initializer_list<value_type> init)
869 for (
auto it : init) {
870 construct(it->first, it->second);
877 return unsafe_at(key).get()->second;
879 throw std::out_of_range(
"direct_map: key out of range");
884 return std::move(unsafe_at(key).
get()->second);
886 throw std::out_of_range(
"direct_map: key out of range");
891 return unsafe_at(key).get()->second;
893 throw std::out_of_range(
"direct_map: key out of range");
898 return std::move(unsafe_at(key).
get()->second);
900 throw std::out_of_range(
"direct_map: key out of range");
905 std::is_nothrow_default_constructible<T>::value) {
906 return try_emplace(key).first->second;
910 return {
this, cbegin().pos};
913 return {
this, cbegin().pos};
923 return {
this, key_range};
928 return {
this, key_range};
931 return {
this, key_range};
934 return {
this, key_range};
938 return std::make_reverse_iterator(end());
942 return std::make_reverse_iterator(end());
946 return std::make_reverse_iterator(crend());
950 return std::make_reverse_iterator(begin());
954 return std::make_reverse_iterator(begin());
958 return std::make_reverse_iterator(cbegin());
976 constexpr auto clear() noexcept ->
void {
978 auto j =
static_cast<Key
>(i);
980 unsafe_at(j).destroy();
988 construct(value.first, value.second);
989 return {{
this, index(value.first)},
true};
991 return {{
this, index(value.first)},
false};
994 template <
typename U>
997 std::pair<iterator, bool>> {
999 construct(value.first, std::forward<U>(value.second));
1000 return {{
this, index(value.first)},
true};
1002 return {{
this, index(value.first)},
false};
1007 construct(value.first, std::move(value.second));
1008 return {{
this, index(value.first)},
true};
1010 return {{
this, index(value.first)},
false};
1014 template <
typename U>
1016 -> std::pair<iterator, bool> {
1018 construct(key, std::forward<U>(value));
1019 return {{
this, index(key)},
true};
1021 *unsafe_at(key).get() = std::forward<U>(value);
1022 return {{
this, index(key)},
false};
1025 template <
typename... Args>
1027 -> std::pair<iterator, bool> {
1029 construct(key, std::forward<Args>(args)...);
1030 return {{
this, index(key)},
true};
1032 return {{
this, index(key)},
false};
1037 destroy(to_key(pos.pos));
1041 destroy(to_key(pos.pos));
1046 for (
auto i :
range(first.pos, last.pos)) {
1054 constexpr auto erase(Key key)
noexcept -> std::size_t {
1064 std::is_nothrow_move_constructible<value_type>::value and
1069 if (other.contains(
k)) {
1071 other.unsafe_at(
k).get()->second);
1073 other.construct(
k, std::move(unsafe_at(
k).
get()->second));
1076 }
else if (other.contains(
k)) {
1077 construct(
k, std::move(other.unsafe_at(
k).get()->second));
1084 swap(active_elems, other.active_elems);
1085 swap(_size, other._size);
1089 return bitmap().test(uindex(key));
1106 -> std::pair<iterator, iterator> {
1107 return {lower_bound(key), upper_bound(key)};
1110 -> std::pair<const_iterator, const_iterator> {
1111 return {lower_bound(key), upper_bound(key)};
1118 return ++
iterator{
this, index(key)};
1126 return ++
iterator{
this, index(key)};
1132 auto l = lower_bound(key);
1133 if (l.pos == index(key)) {
1143 auto l = lower_bound(key);
1144 if (l.pos == index(key)) {
1161 const direct_map& r)
noexcept(
noexcept(std::declval<T&>()
1162 == std::declval<T&>())) ->
bool {
1163 if (l.size() != r.size()) {
1167 if (l.contains(i) != r.contains(i)) {
1169 }
else if (l.contains(i)) {
1170 if (l.at(i) != r.at(i)) {
1180 const direct_map& r)
noexcept(
noexcept(std::declval<T&>()
1181 == std::declval<T&>())) ->
bool {
1182 return not (l == r);
1187 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
1188 std::declval<T&>())) ->
bool {
1194 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
1195 std::declval<T&>())) ->
bool {
1200 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
1201 std::declval<T&>())) ->
bool {
1206 const direct_map& r)
noexcept(
noexcept(std::declval<T&>(),
1207 std::declval<T&>())) ->
bool {
1226 return active_elems;
1229 -> const
std::bitset<key_range>& {
1230 return active_elems;
1233 KBLIB_NODISCARD constexpr auto unsafe_at(Key key) & -> storage_type& {
1234 return elems[uindex(key)];
1236 KBLIB_NODISCARD constexpr auto unsafe_at(Key key) && -> storage_type&& {
1237 return elems[uindex(key)];
1241 return elems[uindex(key)];
1245 return elems[uindex(key)];
1248 template <
typename... Args>
1249 constexpr auto construct(Key key, Args&&... args)
noexcept(
1250 std::is_nothrow_constructible<value_type, Args&&...>::value) ->
void {
1251 if (not active_elems.test(uindex(key))) {
1252 do_construct(key, std::forward<Args>(args)...);
1254 active_elems.set(uindex(key));
1259 template <
typename... Args>
1260 constexpr auto do_construct(Key key, Args&&... args)
noexcept(
1261 std::is_nothrow_constructible<value_type, Args&&...>::value) ->
void {
1262 elems[uindex(key)].construct(
1263 std::piecewise_construct, std::forward_as_tuple(key),
1264 std::forward_as_tuple(std::forward<Args>(args)...));
1267 auto destroy(Key key) ->
void {
1270 bitmap().reset(uindex(key));
1271 unsafe_at(key).destroy();
1277 std::bitset<key_range> active_elems;
1278 std::array<storage_type, key_range> elems;
1280 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
The main namespace in which all entities from kblib are defined.
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))...})>
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.