4#include "Stroika/Foundation/Containers/Adapters/Adder.h"
6#include "Stroika/Foundation/Execution/Common.h"
7#include "Stroika/Foundation/Execution/Throw.h"
9namespace Stroika::Foundation::Memory {
16 template <
typename RHS_CONVERTIBLE_TO_OPTIONAL_OF_T, constructible_from<RHS_CONVERTIBLE_TO_OPTIONAL_OF_T> T>
19 return from ==
nullptr ? nullopt : optional<T>{
static_cast<T
> (*from)};
27 template <
typename T, convertible_to<T> CONVERTIBLE_TO_T, convertible_to<function<T (T, T)>> OP>
28 void AccumulateIf (optional<T>* lhsOptionalValue,
const optional<CONVERTIBLE_TO_T>& rhsOptionalValue,
const OP& op)
31 if (lhsOptionalValue->has_value ()) {
32 if (rhsOptionalValue.has_value ()) {
33 *lhsOptionalValue = op (**lhsOptionalValue,
static_cast<T
> (*rhsOptionalValue));
36 else if (rhsOptionalValue.has_value ()) {
37 *lhsOptionalValue =
static_cast<T
> (*rhsOptionalValue);
40 template <
typename T, convertible_to<function<T (T, T)>> OP>
41 inline void AccumulateIf (optional<T>* lhsOptionalValue,
const T& rhsValue,
const OP& op)
44 if (lhsOptionalValue->has_value ()) {
45 *lhsOptionalValue = op (**lhsOptionalValue, rhsValue);
48 *lhsOptionalValue = rhsValue;
51 template <
typename T,
template <
typename>
typename CONTAINER>
52 requires (is_convertible_v<typename Containers::Adapters::Adder<CONTAINER<T>>::value_type, T>)
53 void AccumulateIf (optional<CONTAINER<T>>* lhsOptionalValue,
const optional<T>& rhsOptionalValue)
56 if (rhsOptionalValue.has_value ()) {
57 if (not lhsOptionalValue->has_value ()) {
58 *lhsOptionalValue = CONTAINER<T>{};
60 Containers::Adapters::Adder<CONTAINER<T>>::Add (&**lhsOptionalValue, *rhsOptionalValue);
63 template <
typename T,
template <
typename>
typename CONTAINER>
64 requires (is_convertible_v<typename Containers::Adapters::Adder<CONTAINER<T>>::value_type, T>)
65 void AccumulateIf (optional<CONTAINER<T>>* lhsOptionalValue,
const T& rhsValue)
68 if (not lhsOptionalValue->has_value ()) {
69 *lhsOptionalValue = CONTAINER<T>{};
71 Containers::Adapters::Adder<CONTAINER<T>>::Add (&**lhsOptionalValue, rhsValue);
73 template <
typename T, convertible_to<T> CONVERTIBLE_TO_T, convertible_to<function<T (T, T)>> OP>
74 inline optional<T>
AccumulateIf (
const optional<T>& lhsOptionalValue,
const optional<CONVERTIBLE_TO_T>& rhsOptionalValue,
const OP& op)
76 optional<T> result{lhsOptionalValue};
80 template <
typename T, convertible_to<function<T (T, T)>> OP>
81 inline optional<T>
AccumulateIf (
const optional<T>& lhsOptionalValue,
const T& rhsValue,
const OP& op)
83 optional<T> result{lhsOptionalValue};
87 template <
typename T,
template <
typename>
typename CONTAINER>
88 requires (is_convertible_v<typename Containers::Adapters::Adder<CONTAINER<T>>::value_type, T>)
89 optional<CONTAINER<T>> AccumulateIf (
const optional<CONTAINER<T>>& lhsOptionalValue,
const optional<T>& rhsOptionalValue)
91 optional<T> result{lhsOptionalValue};
95 template <
typename T,
template <
typename>
typename CONTAINER>
96 requires (is_convertible_v<typename Containers::Adapters::Adder<CONTAINER<T>>::value_type, T>)
97 optional<CONTAINER<T>> AccumulateIf (
const optional<CONTAINER<T>>& lhsOptionalValue,
const T& rhsValue)
99 optional<T> result{lhsOptionalValue};
109 template <
typename T,
typename CONVERTABLE_TO_TYPE>
110 inline void CopyToIf (CONVERTABLE_TO_TYPE* to,
const optional<T>& copyFromIfHasValue)
112 if (copyFromIfHasValue) {
115 *to =
static_cast<CONVERTABLE_TO_TYPE
> (*copyFromIfHasValue);
118 template <
typename T,
typename CONVERTABLE_TO_OPTIONAL_OF_TYPE>
119 inline void CopyToIf (optional<CONVERTABLE_TO_OPTIONAL_OF_TYPE>* to,
const optional<T>& copyFromIfHasValue)
121 if (copyFromIfHasValue) {
124 *to =
static_cast<CONVERTABLE_TO_OPTIONAL_OF_TYPE
> (*copyFromIfHasValue);
133 template <Private_::INullCoalescable OT>
141 template <Private_::INullCoalescable OT, convertible_to<const Private_::OptionalType2ValueType<OT>&> DEFAULT_TYPE>
142 inline const Private_::OptionalType2ValueType<OT>& NullCoalesce (
const OT& l,
const DEFAULT_TYPE& r)
155 template <
typename T>
156 constexpr const T&
ValueOf (
const optional<T>& t)
167 template <
typename T,
typename EXCEPT>
168 inline const T& ValueOfOrThrow (
const optional<T>& t,
const EXCEPT& throwIfNull)
179 template <
typename OUT_T, Common::explicitly_convertible_to<OUT_T> IN_T>
187 template <
typename OUT_T,
typename IN_T, invocable<IN_T> IN_TO_OUT_CONVERTER>
188 inline optional<OUT_T> OptionallyCopy (
const optional<IN_T>& in, IN_TO_OUT_CONVERTER&& cvt)
189 requires (convertible_to<invoke_result_t<IN_TO_OUT_CONVERTER, IN_T>, optional<OUT_T>>)
192 return forward<IN_TO_OUT_CONVERTER> (cvt) (*in);
202 template <
typename T>
203 inline optional<T> operator+ (
const optional<T>& lhs,
const optional<T>& rhs)
210 template <
typename T>
211 inline optional<T> operator+ (
const optional<T>& lhs,
const T& rhs)
218 template <
typename T>
219 inline optional<T> operator+ (
const T& lhs,
const optional<T>& rhs)
232 template <
typename T>
233 inline optional<T> operator- (
const optional<T>& lhs,
const optional<T>& rhs)
240 template <
typename T>
241 inline optional<T> operator- (
const optional<T>& lhs,
const T& rhs)
248 template <
typename T>
249 inline optional<T> operator- (
const T& lhs,
const optional<T>& rhs)
262 template <
typename T>
263 inline optional<T> operator* (
const optional<T>& lhs,
const optional<T>& rhs)
266 return (*lhs) * (*rhs);
270 template <
typename T>
271 inline optional<T> operator* (
const optional<T>& lhs,
const T& rhs)
278 template <
typename T>
279 inline optional<T> operator* (
const T& lhs,
const optional<T>& rhs)
292 template <
typename T>
293 inline optional<T> operator/ (
const optional<T>& lhs,
const optional<T>& rhs)
299 template <
typename T>
300 inline optional<T> operator/ (
const optional<T>& lhs,
const T& rhs)
307 template <
typename T>
308 inline optional<T> operator/ (
const T& lhs,
const optional<T>& rhs)
#define RequireNotNull(p)
optional< OUT_T > OptionallyCopy(const optional< IN_T > &in)
if you can copy an IN_T to an OUT_T, you should be able to copy an optional<IN_T> to an optional<OUT_...
const OT & NullCoalesce(const OT &l, const OT &r)
return one of l, or r, with first preference for which is engaged, and second preference for left-to-...
constexpr optional< T > OptionalFromNullable(const RHS_CONVERTIBLE_TO_OPTIONAL_OF_T *from)
void AccumulateIf(optional< T > *lhsOptionalValue, const optional< CONVERTIBLE_TO_T > &rhsOptionalValue, const OP &op=OP{})
AccumulateIf () add in the rhs argument value to lhs optional, but if both were missing leave 'lhs' a...
constexpr const T & ValueOf(const optional< T > &t)
Same as *t, but Requires that 't' is engaged.
void CopyToIf(CONVERTABLE_TO_TYPE *to, const optional< T > ©FromIfHasValue)
void ThrowIfNull(const Private_::ConstVoidStar &p, const HRESULT &hr)
Template specialization for ThrowIfNull (), for thing being thrown HRESULT - really throw HRESULTErro...