19 template <
typename V1,
typename V2>
21 : std::is_same<typename V1::attribute_t, typename V2::attribute_t> {};
28 template <
typename...>
33 template <
typename... U>
39 namespace __impl_has_attr {
40 template <
typename Pack,
typename Attr>
44 const typename Attr::template value_t<T>&) {
47 static constexpr std::false_type
HasAttr(...) {
return {}; }
49 using type = decltype(HasAttr(std::declval<Pack>()));
53 template <
typename Pack,
typename Attr>
55 template <
typename Pack,
typename Attr>
58 namespace __impl_attr_base {
59 template <
typename Attr,
template <
typename>
class Value>
69 constexpr decltype(
auto) operator()(
value_t<T>& value)
const {
74 constexpr decltype(
auto) operator()(const
value_t<T>& value)
const {
79 constexpr decltype(
auto) operator()(
value_t<T>&& value)
const {
80 return std::move(value);
84 constexpr decltype(
auto) operator()(const
value_t<T>&& value)
const {
85 return std::move(value);
110 return *std::move(target);
115 return *std::move(target);
122 template <
class T,
class... U>
123 static constexpr
auto __impl_CallOrGetAttribute(
124 const std::true_type& isCallable, T&& target, U&&... args) {
125 return Make(Get(std::forward<T>(target))(std::forward<U>(args)...));
129 template <
class T,
class... U>
130 static constexpr
auto __impl_CallOrGetAttribute(
131 const std::false_type& isCallable, T&& target, U&&... args) {
132 return GetAttribute(std::forward<T>(target));
141 template <
class V,
class... U>
142 constexpr decltype(
auto) operator()(V&& target, U&&... args)
const {
143 using ValueOfTargetType = decltype(Get(std::forward<V>(target)));
145 return __impl_CallOrGetAttribute(
148 decltype(std::forward<U>(args))...>{},
149 std::forward<V>(target), std::forward<U>(args)...);
151 } CallOrGetAttribute{};
155 template <
typename Pack,
typename M,
typename D,
typename... U>
156 static constexpr decltype(
auto) __impl_MapOrElse(
const std::true_type&,
157 Pack&& pack, M&& map,
159 return std::forward<M>(map)(GetAttribute(std::forward<Pack>(pack)));
162 template <
typename Pack,
typename M,
typename D,
typename... U>
163 static constexpr decltype(
auto) __impl_MapOrElse(
const std::false_type&,
167 return std::forward<D>(defaultFunction)(std::forward<U>(args)...);
172 template <
typename Pack,
typename M,
typename D,
typename... U>
173 constexpr decltype(
auto) operator()(Pack&& pack, M&& map,
176 return __impl_MapOrElse(
178 std::forward<Pack>(pack), std::forward<M>(map),
179 std::forward<D>(defaultFunction), std::forward<U>(args)...);
184 template <
typename Pack,
typename D,
typename... U>
185 constexpr decltype(
auto) operator()(Pack&& pack, D&& defaultFunction,
187 return MapOrElse(std::forward<Pack>(pack), GetAttribute,
188 std::forward<D>(defaultFunction),
189 std::forward<U>(args)...);
191 } GetAttributeOrElse{};
194 template <
class Pack,
class F,
class... U>
195 constexpr decltype(
auto) operator()(Pack&& pack, F&& defaultFunction,
197 return MapOrElse(std::forward<Pack>(pack), Get,
198 std::forward<F>(defaultFunction),
199 std::forward<U>(args)...);
210 constexpr decltype(
auto) operator()()
const {
211 return std::forward<D>(value);
217 template <
class Pack,
class D>
218 constexpr decltype(
auto) operator()(Pack&& pack,
219 D&& defaultValue)
const {
220 return GetOrElse(std::forward<Pack>(pack),
221 Default<D&&>{std::forward<D>(defaultValue)});
228 template <
typename...>
229 struct FallbackHandler;
231 template <
typename Fallback>
232 struct FallbackHandler<Fallback> {
234 constexpr FallbackHandler(Fallback fallback)
235 : fallback(std::forward<Fallback>(fallback)) {}
237 constexpr decltype(
auto) operator()()
const {
238 return GetAttribute(std::forward<Fallback>(fallback));
242 template <
typename Fallback0,
typename Fallback1,
typename... Fallbacks>
243 struct FallbackHandler<Fallback0, Fallback1, Fallbacks...> {
245 FallbackHandler<Fallback1, Fallbacks...> fallbacks;
246 constexpr FallbackHandler(Fallback0&& fallback0,
247 Fallback1&& fallback1,
248 Fallbacks&&... fallbacks)
249 : fallback(std::forward<Fallback0>(fallback0)),
250 fallbacks(std::forward<Fallback1>(fallback1),
251 std::forward<Fallbacks>(fallbacks)...) {}
253 constexpr decltype(
auto) operator()() && {
254 return GetAttributeOrElse(std::forward<Fallback0>(fallback),
255 std::move(fallbacks));
261 template <
class... Fallbacks>
262 constexpr decltype(
auto) operator()(Fallbacks&&... fallbacks)
const {
263 return FallbackHandler<Fallbacks&&...>{
264 std::forward<Fallbacks>(fallbacks)...}();
266 } GetAttributeOrGetAttributeIn{};
269 template <
class... Fallbacks>
270 constexpr decltype(
auto) operator()(Fallbacks&&... fallbacks)
const {
271 return Get(FallbackHandler<Fallbacks&&...>{
272 std::forward<Fallbacks>(fallbacks)...}());
276 template <
class T,
class V>
278 Get(target) = std::forward<V>(value);
285 return {std::forward<T>(value)};
290 template <
typename Attr,
template <
typename>
class Value>
294 template <
typename Attr,
template <
typename>
class Value>
298 template <
typename Attr,
template <
typename>
class Value>
302 template <
typename Attr,
template <
typename>
class Value>
306 template <
typename Attr,
template <
typename>
class Value>
310 template <
typename Attr,
template <
typename>
class Value>
314 template <
typename Attr,
template <
typename>
class Value>
318 template <
typename Attr,
template <
typename>
class Value>
323 template <
typename Attr,
template <
typename>
class Value>
327 template <
typename Attr,
template <
typename>
class Value>
331 template <
typename Attr,
template <
typename>
class Value>
337 #define DEFINE_ATTR(NAME) \ 339 struct NAME##Value; \ 340 constexpr struct NAME \ 341 : emp::tools::__impl_attr_base::AttrBase<NAME, NAME##Value> { \ 342 static constexpr auto name = #NAME; \ 343 template <typename T> \ 344 constexpr value_t<std::decay_t<T>> operator()(T&& value) const { \ 345 return {std::forward<T>(value)}; \ 348 constexpr const char* NAME::name; \ 350 struct NAME##Value : emp::tools::value_tag, NAME { \ 355 static constexpr auto name = #NAME; \ 356 using attribute_t = struct NAME; \ 357 using attributes_t = emp::tools::Attrs<NAME##Value<T>>; \ 359 NAME##Value() = delete; \ 360 constexpr NAME##Value(const T& value) : value(value) {} \ 361 constexpr NAME##Value(T&& value) : value(std::move(value)) {} \ 362 template <typename U = T> \ 363 constexpr NAME##Value(const NAME##Value<U>& other) : value(*other) {} \ 364 template <typename U = T> \ 365 constexpr NAME##Value(NAME##Value<U>&& other) \ 366 : value(*std::move(other)) {} \ 367 constexpr NAME##Value& operator=(const T& value) { \ 370 this->value = value; \ 373 constexpr NAME##Value& operator=(T&& value) { \ 375 this->value = std::move(value); \ 378 template <typename U = T> \ 379 constexpr NAME##Value& operator=(const NAME##Value<U>& other) { \ 384 template <typename U = T> \ 385 constexpr NAME##Value& operator=(NAME##Value<U>&& other) { \ 387 value = *std::move(other); \ 390 constexpr const T& Get##NAME() const & { return value; } \ 391 constexpr const T&& Get##NAME() const && { return std::move(value); } \ 392 constexpr const T& Get() const & { return value; } \ 393 constexpr const T&& Get() const && { return std::move(value); } \ 394 template <typename U = T> \ 395 constexpr const NAME##Value& Set##NAME(U&& value) { \ 396 this->value = std::forward<U>(value); \ 399 template <typename U = T> \ 400 constexpr const NAME##Value& Set(U&& value) { \ 401 return Set##NAME(std::forward<U>(value)); \ 403 template <typename U = T> \ 404 constexpr const NAME##Value& Set(const NAME##Value<U>& value) { \ 405 return Set##NAME(*value); \ 407 template <typename U = T> \ 408 constexpr const NAME##Value& Set(NAME##Value<U>&& value) { \ 409 return Set##NAME(*std::move(value)); \ 411 constexpr T& operator*() & { return value; } \ 412 constexpr T&& operator*() && { return std::move(value); } \ 413 constexpr const T& operator*() const & { return value; } \ 414 constexpr const T&& operator*() const && { return std::move(value); } \ 415 template <typename M> \ 416 constexpr auto Map(M&& map) & { \ 417 return attribute_t::Make(std::forward<M>(value)); \ 419 template <typename M> \ 420 constexpr auto Map(M&& map) const & { \ 421 return attribute_t::Make(std::forward<M>(value)); \ 423 template <typename M> \ 424 constexpr auto Map(M&& map) && { \ 425 return attribute_t::Make(std::forward<M>(std::move(value))); \ 427 template <typename M> \ 428 constexpr auto Map(M&& map) const && { \ 429 return attribute_t::Make(std::forward<M>(std::move(value))); \ 432 template <typename T> \ 433 constexpr const char* NAME##Value<T>::name; \ 434 template <class A, class B> \ 435 constexpr bool operator==(const NAME##Value<A>& a, \ 436 const NAME##Value<B>& b) { \ 437 return NAME::Get(a) == NAME::Get(b); \ 440 std::ostream& operator<<(std::ostream& out, const NAME##Value<T>& value) { \ 441 return out << #NAME "(" << value.Get() << ")"; \ 444 namespace __attrs_impl {
446 template <
class... T>
456 template <
class... X>
461 template <
class... X>
466 static args_tag Detect(...) {
return {}; }
469 using type = decltype(Detect(std::declval<U>()));
474 typename __attrs_impl_constructor_detector<U>::type;
478 template <
class... U>
480 : T{std::forward<U>(args)}... {}
482 template <
class... U>
484 : T{T::attribute_t::Get(other)}... {}
486 template <
class... U>
488 : T{T::attribute_t::Get(std::move(other))}... {}
498 template <
typename... T>
501 namespace __impl_attrs_reduce {
506 struct AttrsIter<__impl_variadics_type_traits::pack<>> {
507 template <
typename I,
typename R,
typename... A>
508 static constexpr I&&
MergeReduce(I&& init, R&& reducer, A&&... attrs) {
509 return std::forward<I>(init);
511 template <
typename I,
typename R,
typename... A>
512 static constexpr I&&
Reduce(I&& init, R&& reducer, A&&... attrs) {
513 return std::forward<I>(init);
516 template <
typename F,
typename... A>
519 template <
typename F,
typename... A>
520 static constexpr
void Foreach(F&& callback, A&&... attrs) {}
523 template <
typename U>
524 struct AttrsIter<__impl_variadics_type_traits::pack<U>> {
525 template <
typename I,
typename R,
typename... A>
526 static constexpr
auto MergeReduce(I&& init, R&& reducer, A&&... attrs) {
527 return std::forward<R>(reducer)(
528 std::forward<I>(init), U::attribute_t::GetAttributeOrGetAttributeIn(
529 std::forward<A>(attrs)...));
531 template <
typename I,
typename R,
typename... A>
532 static constexpr
auto Reduce(I&& init, R&& reducer, A&&... attrs) {
533 return std::forward<R>(reducer)(
534 std::forward<I>(init),
535 U::attribute_t::GetAttribute(std::forward<A>(attrs))...);
537 template <
typename F,
typename... A>
539 std::forward<F>(callback)(
540 U::attribute_t::GetAttributeOrGetAttributeIn(
541 std::forward<A>(attrs)...));
543 template <
typename F,
typename... A>
544 static constexpr
void Foreach(F&& callback, A&&... attrs) {
545 std::forward<F>(callback)(
546 U::attribute_t::GetAttribute(std::forward<A>(attrs))...);
550 template <
typename U0,
typename U1,
typename... U>
551 struct AttrsIter<__impl_variadics_type_traits::pack<U0, U1, U...>> {
552 template <
typename I,
typename R,
typename... A>
553 static constexpr
auto MergeReduce(I&& init, R&& reducer, A&&... attrs) {
555 decltype(reducer(std::forward<I>(init),
556 U0::attribute_t::GetAttributeOrGetAttributeIn(
557 std::forward<A>(attrs)...)));
561 reducer(std::forward<I>(init),
562 U0::attribute_t::GetAttributeOrGetAttributeIn(
563 std::forward<A>(attrs)...))),
564 std::forward<R>(reducer), std::forward<A>(attrs)...);
567 template <
typename I,
typename R,
typename... A>
568 static constexpr
auto Reduce(I&& init, R&& reducer, A&&... attrs) {
569 using new_init_t = decltype(
570 reducer(std::forward<I>(init),
571 U0::attribute_t::GetAttribute(std::forward<A>(attrs))...));
574 Reduce(std::forward<new_init_t>(reducer(
575 std::forward<I>(init),
576 U0::attribute_t::GetAttribute(std::forward<A>(attrs))...)),
577 std::forward<R>(reducer), std::forward<A>(attrs)...);
580 template <
typename F,
typename... A>
582 callback(U0::attribute_t::GetAttributeOrGetAttributeIn(
583 std::forward<A>(attrs)...));
586 MergeForeach(std::forward<F>(callback), std::forward<A>(attrs)...);
589 template <
typename F,
typename... A>
590 static constexpr
void Foreach(F&& callback, A&&... attrs) {
591 callback(U0::attribute_t::GetAttribute(std::forward<A>(attrs))...);
594 Foreach(std::forward<F>(callback), std::forward<A>(attrs)...);
600 template <
typename I,
typename R,
typename... A>
605 Attrs,
typename std::decay_t<A>::attributes_t>...>>
:: 606 MergeReduce(std::forward<I>(init), std::forward<R>(reducer),
607 std::forward<A>(attrs)...);
610 template <
typename I,
typename R,
typename... A>
611 constexpr
auto Reduce(I&& init, R&& reducer, A&&... attrs) {
615 Attrs,
typename std::decay_t<A>::attributes_t>...>>
:: 616 Reduce(std::forward<I>(init), std::forward<R>(reducer),
617 std::forward<A>(attrs)...);
620 template <
typename F,
typename... A>
625 Attrs,
typename std::decay_t<A>::attributes_t>...>>
:: 626 MergeForeach(std::forward<F>(callback), std::forward<A>(attrs)...);
628 template <
typename F,
typename... A>
629 constexpr
void Foreach(F&& callback, A&&... attrs) {
633 Attrs,
typename std::decay_t<A>::attributes_t>...>>
:: 634 Foreach(std::forward<F>(callback), std::forward<A>(attrs)...);
637 template <
typename... T>
643 constexpr
Attrs() : __attrs_impl::AttrsParent<T...>{} {}
661 template <
class U0,
class... U>
662 constexpr
Attrs(U0&& arg, U&&... args)
669 std::forward<U0>(arg), std::forward<U>(args)...) {}
672 constexpr
static struct __impl_AssignOp_asssigner_t {
673 template <
typename T1,
typename T2>
674 constexpr
void operator()(T1& to, T2&& from)
const {
675 to = std::forward<T2>(from);
677 } __impl_AssignOp_asssigner{};
680 template <
typename F>
683 std ::forward<F>(from));
689 template <
bool Last,
typename A>
691 template <
typename A>
692 struct GetAttr<false, A> {
693 template <
typename S,
typename... U>
694 static constexpr decltype(
auto) Get(S&& Self, U&&... args) {
695 using attribute_t =
typename A::attribute_t;
696 return attribute_t::CallOrGetAttribute(std::forward<S>(Self),
701 template <
typename A>
702 struct GetAttr<true, A> {
703 template <
typename S,
typename... U>
704 static constexpr decltype(
auto) Get(S&& Self, U&&... args) {
705 using attribute_t =
typename A::attribute_t;
706 return attribute_t::CallOrGetAttribute(std::forward<S>(Self),
707 std::forward<U>(args)...);
711 template <
typename S,
typename... U>
712 static constexpr
auto Call(S&& Self, U&&... args) {
713 constexpr
size_t last =
sizeof...(T) - 1;
715 GetAttr<variadic_index_of_v<T, Attrs> == last,
716 T>::
template Get<S, U...>(std::forward<S>(Self),
717 std::forward<U>(args)...)...);
727 template <
class... U>
729 return Call(*
this, std::forward<U>(args)...);
732 template <
class... U>
734 return Call(*
this, std::forward<U>(args)...);
737 template <
class... U>
739 return Call(std::move(*
this), std::forward<U>(args)...);
742 template <
class... U>
744 return Call(std::move(*
this), std::forward<U>(args)...);
749 template <
typename A,
typename B>
750 constexpr
bool operator()(
bool init, A&& a, B&& b)
const {
751 return init && (std::forward<A>(a).Get() == std::forward<B>(b).Get());
759 template <
class... U>
767 template <
typename F>
768 struct __impl_reduce_from_reduce_value {
770 constexpr __impl_reduce_from_reduce_value(F callback)
771 : callback(std::forward<F>(callback)) {}
772 template <
typename I,
typename U>
773 constexpr
auto operator()(I&& init, U&& value) {
774 return std::forward<F>(callback)(value.name, std::forward<I>(init),
775 *std::forward<U>(value));
780 template <
typename I,
typename F>
783 std::forward<F>(callback), *
this);
785 template <
typename I,
typename F>
788 std::forward<F>(callback), *
this);
790 template <
typename I,
typename F>
793 std::forward<F>(callback), std::move(*
this));
795 template <
typename I,
typename F>
798 std::forward<F>(callback), std::move(*
this));
801 template <
typename I,
typename F>
802 constexpr
auto Reduce(I&& init, F&& callback) {
803 return AttributeReduce(
804 std::forward<I>(init),
805 __impl_reduce_from_reduce_value<F&&>{std::forward<F>(callback)});
807 template <
typename I,
typename F>
808 constexpr
auto Reduce(I&& init, F&& callback)
const {
809 return AttributeReduce(
810 std::forward<I>(init),
811 __impl_reduce_from_reduce_value<F&&>{std::forward<F>(callback)});
815 template <
typename F>
816 struct __impl_foreach_from_foreach_value {
818 constexpr __impl_foreach_from_foreach_value(F callback)
819 : callback(std::forward<F>(callback)) {}
820 template <
typename U>
821 constexpr
void operator()(U&& value) {
822 std::forward<F>(callback)(value.name, *std::forward<U>(value));
827 template <
typename F>
832 template <
typename F>
837 template <
typename F>
842 template <
typename F>
847 template <
typename F>
850 __impl_foreach_from_foreach_value<decltype(
851 std::forward<F>(callback))>{std::forward<F>(callback)});
854 template <
typename F>
857 __impl_foreach_from_foreach_value<decltype(
858 std::forward<F>(callback))>{std::forward<F>(callback)});
862 template <
typename S,
typename U>
863 constexpr
static Attrs<T..., std::decay_t<U>> __impl_SetAttribute(
864 const std::false_type& has_attr, S&&
self, U&& attribute) {
865 return MakeAttrs(T::attribute_t::GetAttribute(std::forward<S>(
self))...,
866 std::forward<U>(attribute));
868 template <
typename S,
typename U>
869 constexpr
static auto __impl_SetAttribute(
const std::true_type& has_attr,
870 S&&
self, U&& attribute) {
871 return MakeAttrs(T::attribute_t::GetAttributeOrGetAttributeIn(
872 std::forward<S>(
self), std::forward<U>(attribute))...);
875 template <
typename S,
typename U>
876 constexpr
static auto __impl_SetAttribute(S&&
self, U&& attribute) {
877 return __impl_SetAttribute(
879 std::forward<S>(
self), std::forward<U>(attribute));
883 template <
typename U>
885 return __impl_SetAttribute(*
this, std::forward<U>(attribute));
888 template <
typename U>
890 return __impl_SetAttribute(*
this, std::forward<U>(attribute));
893 template <
typename U>
895 return __impl_SetAttribute(std::move(*
this),
896 std::forward<U>(attribute));
899 template <
typename U>
901 return __impl_SetAttribute(std::move(*
this),
902 std::forward<U>(attribute));
906 template <
typename... T>
907 constexpr
typename Attrs<T...>::__impl_AssignOp_asssigner_t
908 Attrs<T...>::__impl_AssignOp_asssigner;
912 template <
class... T>
914 return {std::forward<T>(props)...};
917 namespace __impl_attrs_merge {
919 template <
typename I,
typename A>
920 constexpr
auto operator()(I&& init, A&& next)
const {
921 return std::forward<I>(init).SetAttribute(std::forward<A>(next));
929 template <
typename... U>
933 std::forward<U>(packs)...)) {
935 std::forward<U>(packs)...);
938 namespace __attrs_impl {
942 template <
class... T,
class H>
945 out <<
'"' << H::name <<
"\": " << H::attribute_t::Get(attrs);
947 template <
class... T,
class H0,
class H1,
class... U>
950 out <<
'"' << H0::name <<
"\": " << H0::attribute_t::Get(attrs) <<
", ";
955 template <
class H,
class... T>
963 std::ostream& operator<<(std::ostream& out, const Attrs<>& attrs) {
969 #endif // EMP_PLOT_EMP Definition: type_traits.h:100
Definition: type_traits.h:91
typename ToPack< Variadic, Pack >::type ToPackType
Definition: type_traits.h:116
typename variadic_intersection< Cmp, U... >::type variadic_intersection_t
Definition: type_traits.h:397
A set of types that can be manipulated at compile time (good for metaprogramming) ...
typename variadic_union< Cmp, U... >::type variadic_union_t
Definition: type_traits.h:336
If we are in emscripten, make sure to include the header.
Definition: array.h:37
Extensions on the standard library type traits to handle Empirical classes (such as Ptr)...
Definition: TypePack.h:71