Iros
 
Loading...
Searching...
No Matches
access.h
Go to the documentation of this file.
1#pragma once
2
17#include "di/meta/core.h"
18#include "di/meta/operations.h"
19#include "di/meta/vocab.h"
22
23namespace di::container {
24namespace detail {
25 struct FrontFunction;
26
27 template<typename T>
29
30 template<typename T>
34
35 template<typename T>
37
39 template<typename T>
41 constexpr auto operator()(T&& container) const -> Optional<meta::ContainerReference<T>> {
42 if constexpr (CustomFront<T>) {
43 static_assert(SameAs<Optional<meta::ContainerReference<T>>, meta::TagInvokeResult<FrontFunction, T&>>,
44 "di::front() customizations must return Optional<meta::ContainerReference<T>>");
45 return function::tag_invoke(*this, container);
46 } else if constexpr (MemberFront<T>) {
47 return container.front();
48 } else {
49 if (empty(container)) {
50 return nullopt;
51 }
52 return *begin(container);
53 }
54 }
55 };
56}
57
58constexpr inline auto front = detail::FrontFunction {};
59
60namespace detail {
61 struct BackFunction;
62
63 template<typename T>
65
66 template<typename T>
70
71 template<typename T>
73
75 template<typename T>
77 constexpr auto operator()(T&& container) const -> Optional<meta::ContainerReference<T>> {
78 if constexpr (CustomBack<T>) {
79 static_assert(SameAs<Optional<meta::ContainerReference<T>>, meta::TagInvokeResult<BackFunction, T&>>,
80 "di::back() customizations must return Optional<meta::ContainerReference<T>>");
81 return function::tag_invoke(*this, container);
82 } else if constexpr (MemberBack<T>) {
83 return container.back();
84 } else {
85 if (empty(container)) {
86 return nullopt;
87 }
88 return *prev(end(container));
89 }
90 }
91 };
92}
93
94constexpr inline auto back = detail::BackFunction {};
95
96namespace detail {
97 struct AtFunction;
98
99 template<typename T, typename K>
101
102 template<typename T, typename K>
103 concept MemberAt = concepts::Container<T> && requires(T&& container, K&& key) {
104 { container.at(di::forward<K>(key)) } -> concepts::Optional;
105 };
106
107 template<typename T, typename K>
109 requires(T& container, meta::IteratorSSizeType<T> index) {
110 { container[index] } -> SameAs<meta::ContainerReference<T>>;
111 };
112
113 template<typename T, typename K>
114 concept IteratorAt =
116
118 template<typename T, typename K>
120 constexpr auto operator()(T&& container, K&& key) const {
121 using SSizeType = meta::ContainerSSizeType<T>;
122 if constexpr (CustomAt<T, K>) {
124 "di::at() customizations must return an Optional");
125 return function::tag_invoke(*this, container, di::forward<K>(key));
126 } else if constexpr (MemberAt<T, K>) {
127 return container.at(di::forward<K>(key));
128 } else {
130
131 auto const size = ssize(container);
132 auto const index = SSizeType(di::forward<K>(key));
133 if (index < 0 || index >= size) {
134 return R(nullopt);
135 }
136
137 if constexpr (IndexAt<T, K>) {
138 return R(container[index]);
139 } else {
140 return R(begin(container)[index]);
141 }
142 }
143 }
144 };
145}
146
147constexpr inline auto at = di::curry_back(detail::AtFunction {}, c_<2ZU>);
148
149namespace detail {
151 template<typename T>
152 constexpr auto operator()(T&& container) const -> decltype(auto)
153 requires(requires { front(di::forward<T>(container)); })
154 {
155 return *front(container);
156 }
157 };
158
160 template<typename T>
161 constexpr auto operator()(T&& container) const -> decltype(auto)
162 requires(requires { back(di::forward<T>(container)); })
163 {
164 return *back(container);
165 }
166 };
167
169 template<typename T, typename K>
170 constexpr auto operator()(T&& container, K&& key) const -> decltype(auto)
171 requires(requires { at(di::forward<T>(container), di::forward<K>(key)); })
172 {
173 return *at(container, di::forward<K>(key));
174 }
175 };
176}
177
181}
182
183namespace di {
184using container::at;
186using container::back;
188using container::front;
190}
Definition optional_forward_declaration.h:5
Definition bidirectional_container.h:8
Definition common_container.h:10
Definition operations.h:11
Definition container.h:8
Definition forward_container.h:8
Implicit conversion for this test refers to the ability to return a value of function from a type.
Definition operations.h:89
Definition vocab.h:77
Definition random_access_container.h:8
Definition tag_invoke.h:33
Definition access.h:36
Definition access.h:100
Definition access.h:64
Definition access.h:108
Definition access.h:114
Definition access.h:103
Definition access.h:67
Definition access.h:72
Definition sequence.h:13
Definition sequence.h:12
constexpr auto prev
Definition prev.h:28
constexpr auto front
Definition access.h:58
constexpr auto empty
Definition empty.h:45
constexpr auto ssize
Definition ssize.h:34
constexpr auto at
Definition access.h:147
constexpr auto back_unchecked
Definition access.h:179
constexpr auto size
Definition size.h:54
constexpr auto front_unchecked
Definition access.h:178
constexpr auto end
Definition end.h:47
constexpr auto back
Definition access.h:94
constexpr auto begin
Definition begin.h:44
constexpr auto at_unchecked
Definition access.h:180
constexpr tag_invoke_detail::TagInvokeFn tag_invoke
Definition tag_invoke.h:22
Definition json_deserializer.h:532
IteratorSSizeType< ContainerIterator< T > > ContainerSSizeType
Definition container_ssize_type.h:8
IteratorReference< ContainerIterator< T > > ContainerReference
Definition container_reference.h:8
decltype(container::iterator_ssize_type(types::in_place_type< meta::RemoveCVRef< T > >)) IteratorSSizeType
Definition iterator_ssize_type.h:8
decltype(di::function::tag_invoke(util::declval< Tag >(), util::declval< Args >()...)) TagInvokeResult
Definition tag_invoke.h:40
Definition zstring_parser.h:9
constexpr auto nullopt
Definition nullopt.h:15
constexpr auto c_
A value of type Constexpr<val>.
Definition constexpr.h:252
constexpr auto curry_back
Definition curry_back.h:141
Definition access.h:117
constexpr auto operator()(T &&container, K &&key) const -> decltype(auto) requires(
Definition access.h:170
constexpr auto operator()(T &&container) const -> decltype(auto) requires(
Definition access.h:161
constexpr auto operator()(T &&container) const -> decltype(auto) requires(
Definition access.h:152