10 #include <type_traits> 13 #include "ValueHolder.h" 19 template <
class H,
class E,
class A>
22 template <
class H,
class E,
class A>
23 std::ostream& operator<<(std::ostream& os, const AnySet<H, E, A>&
set);
31 template <
class S,
class T>
34 template<
class Stream,
class Type>
35 static auto test(
int) -> decltype(
39 template<
class,
class>
43 static constexpr
const bool value = decltype(test<S,T>(0))::value;
52 template <
class T,
class =
void>
59 decltype((void)(std::declval<T>() == std::declval<T>()))
65 template <
class T,
class =
void>
72 decltype((void)(std::declval<T>() != std::declval<T>()), (void)0)
78 template <
class Value,
class HashFn,
class Compare>
81 template <
class Value,
class HashFn,
class Compare>
84 template <
class HashFn,
class Compare>
92 template <
class HashFn,
class Compare>
112 template <
class T,
class H,
class C>
117 template <
class T,
class H,
class C>
120 template <
class T,
class H,
class C>
137 std::logic_error(
"Attempt to copy construct type that is not copy constructible."),
143 virtual const char* what()
const noexcept
override 167 static_assert(not std::is_copy_constructible_v<T>);
179 template <
class T,
class H,
class C,
class ... Args>
182 template <
class T,
class H,
class C,
class ... Args>
216 template <
class T,
class H,
class C,
class ... Args>
238 template <
class T,
class H,
class C,
class ... Args>
268 template <
class HashFn,
class Compare>
272 using hasher = HashFn;
273 using key_equal = Compare;
286 if(
const T* p = try_as<T>(left);
static_cast<bool>(p))
295 if(
const T* p = try_as<T>(right);
static_cast<bool>(p))
304 if(
const T* p = try_as<T>(right);
static_cast<bool>(p))
313 if(
const T* p = try_as<T>(left);
static_cast<bool>(p))
331 {
return left.equals(right); }
347 {
return left.not_equals(right); }
364 {
return left.compare_to(right, comp); }
379 template <
class T,
class Comp = Compare,
class = std::enable_if_t<not std::is_same_v<T, self_type>>>
382 if(
const T* p = try_as<T>(right);
static_cast<bool>(p))
383 return comp(left, *p);
400 template <
class T,
class Comp = Compare,
class = std::enable_if_t<not std::is_same_v<T, self_type>>>
403 if(
const T* p = try_as<T>(left);
static_cast<bool>(p))
404 return comp(*p, right);
439 virtual bool compare_to(
const AnyValue& other, Compare comp)
const = 0;
440 virtual bool equals(
const AnyValue& other)
const = 0;
441 virtual bool not_equals(
const AnyValue& other)
const = 0;
456 template <
class,
class,
class>
465 template <
class Value,
class HashFn,
class Compare>
482 template <
class Value,
class HashFn,
class Compare>
487 using value_type = Value;
489 using self_type = TypedValue<Value, HashFn, Compare>;
490 using link_type = AnyValueLink<Value, HashFn, Compare>;
492 virtual ~TypedValue() =
default;
508 bool equals(
const base_type& other)
const final override 510 if constexpr(detail::is_equality_comparable_v<Value>)
511 if(
const Value* v = try_as<Value>(other);
static_cast<bool>(v))
512 return (*v) == this->value();
519 bool not_equals(
const base_type& other)
const final override 521 if constexpr(detail::is_inequality_comparable_v<Value>)
522 if(
const Value* v = try_as<Value>(other);
static_cast<bool>(v))
523 return (*v) != this->value();
530 bool compare_to(
const base_type& other, Compare comp)
const final override 532 auto* p = try_as<Value>(other);
533 return static_cast<bool>(p) and comp(*p, this->value());
538 if constexpr(detail::is_streamable_v<Value>)
541 os <<
"AnyValue(typeid.name='" << typeinfo().name() <<
"', hash=" << this->hash <<
')';
546 if constexpr(std::is_copy_constructible_v<Value>)
547 return make_any_value<Value, HashFn, Compare>(this->hash, this->value());
553 {
return typeid(Value); }
555 const value_type& value()
const&
556 {
return get_value(as_link()); }
558 const value_type&& value()
const&&
559 {
return std::move(get_value(as_link())); }
562 const link_type& as_link()
const& noexcept
563 {
return static_cast<const link_type&
>(*this); }
565 const link_type&& as_link()
const&& noexcept
566 {
return static_cast<const link_type&&
>(*this); }
592 template <
class Value,
class HashFn,
class Compare>
597 friend struct TypedValue<Value, HashFn, Compare>;
604 template <
class ... Args>
612 template <
class ... Args>
613 AnyValueLink(HashFn hasher, Args&& ... args):
620 friend const Value& get_value(
const self_type&
self)
621 {
return get_value(static_cast<const holder_type&>(
self)); }
623 friend const Value&& get_value(
const self_type&&
self)
624 {
return get_value(static_cast<const holder_type&&>(
self)); }
632 template <
class T,
class H,
class C,
class ... Args>
635 auto tmp = std::make_unique<AnyValueLink<T, H, C>>(hash_v, std::forward<Args>(args) ...);
641 template <
class T,
class H,
class C,
class ... Args>
644 auto tmp = std::make_unique<AnyValueLink<T, H, C>>(hash_fn, std::forward<Args>(args) ...);
650 template <
class T,
class H,
class C,
class ... Args>
653 auto tmp = detail::make_typed_value<T, H, C>(hash_value, std::forward<Args>(args)...);
659 template <
class T,
class H,
class C,
class ... Args>
662 auto tmp = detail::make_typed_value<T, H, C>(hasher, std::forward<Args>(args)...);
707 template <
class To,
class H,
class C>
711 std::is_same_v<
const std::decay_t<To>&, To>,
712 "Can only polymorphic_cast an AnyValue reference to a const reference type." 715 std::is_class_v<std::decay_t<To>> and not std::is_final_v<std::decay_t<To>>,
716 "Cannot 'polymorphic_cast()' to final or non-class type." 718 return dynamic_cast<To
>(any_v);
754 template <
class To,
class H,
class C>
757 using type = std::decay_t<std::remove_pointer_t<std::decay_t<To>>>;
759 std::is_same_v<const type*, To>,
760 "Can only polymorphic_cast an AnyValue pointer to a pointer to const type." 762 static_assert(std::is_class_v<type> and not std::is_final_v<type>,
763 "Cannot 'polymorphic_cast()' to final or non-class type." 765 return dynamic_cast<To
>(any_v);
790 template <
class To,
class H,
class C>
793 using to_type = std::decay_t<To>;
794 if(is<to_type>(any_v))
819 template <
class To,
class H,
class C>
823 std::is_pointer_v<To>,
824 "exact_cast<T>(const AnyValue<H, C>*) requires that T be a pointer type." 826 using to_type = std::decay_t<std::remove_pointer_t<To>>;
827 if(is<to_type>(*any_v))
856 template <
class To,
class H,
class C>
890 template <
class T,
class H,
class C>
893 static_assert(std::is_object_v<T>);
894 if(
const T* p = exact_cast<const T*>(&any_v);
static_cast<bool>(p))
896 else if constexpr(std::is_class_v<T> and not std::is_final_v<T>)
898 if(p = polymorphic_cast<const T*>(&any_v);
static_cast<bool>(p))
928 template <
class T,
class H,
class C>
931 if(
const auto* p = try_as<T>(
self);
static_cast<bool>(p))
936 template <
class T,
class H,
class C>
938 {
return any_v.
typeinfo() ==
typeid(T); }
952 template <
class T,
class H,
class C>
987 template <
class T,
class H,
class C,
class DefaultRef>
991 std::is_same_v<T, std::decay_t<T>>,
992 "T should be a naked type (no cv qualifiers, or refereces) in get_default_ref<T>()" 996 std::is_same_v<std::decay_t<T>, std::decay_t<DefaultRef>>,
997 "The second argument (the 'default') in get_default_ref<T>() must have the same type as T." 1001 not std::is_rvalue_reference_v<decltype(default_ref)>,
1002 "get_default_ref() cannot be called with an rvalue (would return a dangling reference)." 1005 if(
const std::decay_t<T>* p = try_as<T>(any_v);
static_cast<bool>(p))
1008 return std::forward<DefaultRef>(default_ref);
1039 template <
class T,
class H,
class C,
class DefaultVal>
1043 std::is_same_v<T, std::decay_t<T>>,
1044 "T should be a naked type (no cv qualifiers, or refereces) in get_default_val<T>()" 1048 std::is_constructible_v<std::decay_t<T>, DefaultVal>,
1049 "Cannot construct return value of get_default_val() with given argument for the default value (the second arguments)." 1053 std::is_constructible_v<std::decay_t<T>,
const std::decay_t<T>>,
1054 "Cannot construct return value of get_default_val() with the value contained in AnyValue (const reference)." 1057 if(
const T* p = try_as<T>(any_v);
static_cast<bool>(p))
1060 return static_cast<T
>(std::forward<DefaultVal>(default_val));
To exact_cast(const AnyValue< H, C > *any_v)
Access the contained object.
Definition: AnyNode.h:820
friend bool operator!=(const T &left, const AnyValue &right)
Query whether the contained object in right is not of type T or not equal to left.
Definition: AnyNode.h:302
friend bool operator!=(const AnyValue &left, const T &right)
Query whether the contained object in left is not of type T or not equal to right.
Definition: AnyNode.h:311
const std::size_t hash
The hash code obtained by invoking an instance of HashFn on the contained object. ...
Definition: AnyNode.h:453
const T * try_as(const AnyValue< H, C > &any_v)
Get a pointer to the contained object of type T. If the contained object is not an instance of type T...
Definition: AnyNode.h:891
friend bool operator==(const AnyValue &left, const T &right)
Query whether the contained object in left is of type T and equal to right.
Definition: AnyNode.h:284
friend bool operator==(const AnyValue &left, const AnyValue &right)
Query whether the contained objects in left and right are of the same equality-comparable type...
Definition: AnyNode.h:330
friend bool compare(const AnyValue &left, const T &right, Comp comp)
Query whether the contained object in left is of type T and subsequently whether the contained object...
Definition: AnyNode.h:401
CopyConstructionError(const std::type_info &ti)
Construct a CopyConstructionError exception object.
Definition: AnyNode.h:136
friend bool operator==(const T &left, const AnyValue &right)
Query whether the contained object in right is of type T and equal to left.
Definition: AnyNode.h:293
This class is an implementation detail and is not part of the public interface of AnyValue...
Definition: AnyNode.h:79
To polymorphic_cast(const AnyValue< H, C > &any_v)
Access the contained object through a reference to dynamic type To.
Definition: AnyNode.h:708
friend bool compare(const AnyValue &left, const AnyValue &right, Compare comp)
Query whether the contained objects in left and right are of the same type, and subsequently whether ...
Definition: AnyNode.h:363
Definition: ValueHolder.h:13
T get_default_val(const AnyValue< H, C > &any_v, DefaultVal &&default_val)
Get a copy of the contained value in any_v of type T.
Definition: AnyNode.h:1040
Base type of NoCopyConstructorError. Thrown when attempting to make copies of an AnyValue instance th...
Definition: AnyNode.h:128
Exception thrown when attempting to make copies of an AnyValue instance that contains an instance of ...
Definition: AnyNode.h:164
Primary classes and utility functions for AnySet.
Definition: SetOperations.h:21
virtual const std::type_info & typeinfo() const =0
Get a reference to a std::type_info object that indicates the type of the contained object...
To polymorphic_cast(const AnyValue< H, C > *any_v)
Access the contained object through a pointer to dynamic type To.
Definition: AnyNode.h:755
friend bool operator!=(const AnyValue &left, const AnyValue &right)
Query whether the contained objects in left and right are of different types, or whether the containe...
Definition: AnyNode.h:346
const std::type_info & typeinfo
Definition: AnyNode.h:153
const std::type_info & typeinfo() const final override
Get a reference to a std::type_info object that indicates the type of the contained object...
Definition: AnyNode.h:552
To unsafe_cast(const AnyValue< H, C > &any_v)
Access the contained object without dynamic type checking.
Definition: AnyNode.h:857
friend std::ostream & operator<<(std::ostream &os, const AnyValue &any_v)
Write the contained object to the given std::ostream using the stream insertion << operator...
Definition: AnyNode.h:418
AnySet is an associative container that contains a set of unique objects of any constructible type...
Definition: AnySet.h:104
This class is an implementation detail and is not part of the public interface of AnyValue...
Definition: AnyNode.h:82
friend bool compare(const T &left, const AnyValue &right, Comp comp)
Query whether the contained object in right is of type T and subsequently whether the contained objec...
Definition: AnyNode.h:380
const T & as(const AnyValue< H, C > &self)
Get a reference to the contained object of type T. If the contained object is not an instance of type...
Definition: AnyNode.h:929
const std::decay_t< T > & get_default_ref(const AnyValue< H, C > &any_v, DefaultRef &&default_ref)
Get the contained value in any_v through a reference to const T.
Definition: AnyNode.h:988
To exact_cast(const AnyValue< H, C > &any_v)
Access the contained object.
Definition: AnyNode.h:791