28 concept CustomFront = concepts::Container<T> && concepts::TagInvocable<FrontFunction, T&>;
31 concept MemberFront = concepts::Container<T> &&
requires(T&& container) {
32 { container.front() } -> concepts::ImplicitlyConvertibleTo<Optional<meta::ContainerReference<T>>>;
36 concept BeginFront = concepts::ForwardContainer<T>;
38 struct FrontFunction : function::pipeline::EnablePipeline {
40 requires(CustomFront<T> || MemberFront<T> || BeginFront<T>)
42 if constexpr (CustomFront<T>) {
44 "di::front() customizations must return Optional<meta::ContainerReference<T>>");
46 }
else if constexpr (MemberFront<T>) {
47 return container.front();
49 if (
empty(container)) {
52 return *
begin(container);
58constexpr inline auto front = detail::FrontFunction {};
68 {
container.back() } -> concepts::ImplicitlyConvertibleTo<Optional<meta::ContainerReference<T>>>;
72 concept RBeginBack = concepts::BidirectionalContainer<T> && concepts::CommonContainer<T>;
74 struct BackFunction : function::pipeline::EnablePipeline {
76 requires(CustomBack<T> || MemberBack<T> || RBeginBack<T>)
78 if constexpr (CustomBack<T>) {
80 "di::back() customizations must return Optional<meta::ContainerReference<T>>");
82 }
else if constexpr (MemberBack<T>) {
83 return container.back();
85 if (
empty(container)) {
94constexpr inline auto back = detail::BackFunction {};
99 template<
typename T,
typename K>
102 template<
typename T,
typename K>
104 {
container.at(di::forward<K>(key)) } -> concepts::Optional;
107 template<
typename T,
typename K>
108 concept IndexAt = concepts::Container<T> && concepts::ConstructibleFrom<meta::IteratorSSizeType<T>, K> &&
110 { container[index] } -> SameAs<meta::ContainerReference<T>>;
113 template<
typename T,
typename K>
115 concepts::RandomAccessContainer<T> && concepts::ConstructibleFrom<meta::IteratorSSizeType<T>, K>;
117 struct AtFunction : function::pipeline::EnablePipeline {
118 template<
typename T,
typename K>
119 requires(CustomAt<T, K> || MemberAt<T, K> || IndexAt<T, K> || IteratorAt<T, K>)
120 constexpr auto operator()(T&& container, K&& key)
const {
122 if constexpr (CustomAt<T, K>) {
123 static_assert(concepts::Optional<meta::TagInvokeResult<AtFunction, T&, K&&>>,
124 "di::at() customizations must return an Optional");
126 }
else if constexpr (MemberAt<T, K>) {
127 return container.at(di::forward<K>(key));
129 using R = Optional<meta::ContainerReference<T>>;
132 auto const index = SSizeType(di::forward<K>(key));
133 if (index < 0 || index >=
size) {
137 if constexpr (IndexAt<T, K>) {
138 return R(container[index]);
140 return R(
begin(container)[index]);
152 constexpr auto operator()(T&&
container)
const ->
decltype(
auto)
155 return *
front(container);
159 struct BackUncheckedFunction : function::pipeline::EnablePipeline {
161 constexpr auto operator()(T&& container)
const ->
decltype(
auto)
162 requires(
requires {
back(di::forward<T>(container)); })
164 return *
back(container);
168 struct AtUncheckedFunction {
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)); })
173 return *
at(container, di::forward<K>(key));
Definition tag_invoke.h:33
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:62
constexpr auto front_unchecked
Definition access.h:178
constexpr auto end
Definition end.h:55
constexpr auto back
Definition access.h:94
constexpr auto begin
Definition begin.h:52
constexpr auto at_unchecked
Definition access.h:180
constexpr tag_invoke_detail::TagInvokeFn tag_invoke
Definition tag_invoke.h:22
Definition any_storable.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