10 #ifndef TEUCHOS_ANY_HPP
11 #define TEUCHOS_ANY_HPP
18 #include <type_traits>
21 #include "Teuchos_Assert.hpp"
23 #include "Teuchos_Exceptions.hpp"
58 static auto test(
int) -> decltype(std::declval<X>() == std::declval<X>(),
59 void(), std::true_type());
61 static auto test(...) -> std::false_type;
62 using type = decltype(test<T>(0));
69 static auto test(
int) -> decltype(std::declval<std::ostream&>() << std::declval<X>(),
70 void(), std::true_type());
72 static auto test(...) -> std::false_type;
73 using type = decltype(test<T>(0));
76 template <class T, class ok = typename is_comparable<T>::type>
80 struct compare<T, std::false_type> {
81 bool operator()(T
const&, T
const&)
const {
83 "Trying to compare type " <<
typeid(T).name() <<
" which is not comparable");
91 struct compare<T, std::true_type> {
92 bool operator()(T
const& a, T
const& b)
const {
97 template <class T, class ok = typename is_printable<T>::type>
101 struct print<T, std::false_type> {
102 std::ostream& operator()(std::ostream& s, T
const&)
const {
105 " which is not printable (i.e. does not have operator<<() defined)!");
113 struct print<T, std::true_type> {
114 std::ostream& operator()(std::ostream& a, T
const& b)
const {
122 class TEUCHOSCORE_LIB_DLL_EXPORT
any
131 template<
typename ValueType>
132 explicit any(ValueType&& value)
133 : content(new holder<std::decay_t<ValueType>>(std::forward<ValueType>(value)))
138 : content(other.content ? other.content->clone() : 0)
143 : content(std::exchange(other.content,nullptr))
155 std::swap(content, rhs.content);
160 template<
typename ValueType>
178 delete this->content;
179 this->content = std::exchange(other.content,
nullptr);
188 return ! this->has_value();
192 bool has_value()
const {
return this->content !=
nullptr; }
195 const std::type_info &
type()
const
197 return content ? content->type() :
typeid(void);
203 return content ? content->typeName() :
"NONE";
212 if( !this->has_value() && !other.
has_value() )
214 else if( this->has_value() && !other.
has_value() )
216 else if( !this->has_value() && other.
has_value() )
219 return content->same(*other.content);
228 if (content) content->print(os);
231 #ifndef DOXYGEN_SHOULD_SKIP_THIS
240 virtual ~placeholder() {}
242 virtual const std::type_info & type()
const = 0;
244 virtual std::string
typeName()
const = 0;
246 virtual placeholder * clone()
const = 0;
248 virtual bool same(
const placeholder &other )
const = 0;
250 virtual void print(std::ostream & os)
const = 0;
254 template<
typename ValueType>
255 class holder :
public placeholder
259 template <
typename U>
261 : held(std::forward<U>(value))
264 const std::type_info & type()
const
265 {
return typeid(ValueType); }
270 placeholder * clone()
const
271 {
return new holder(held); }
273 bool same(
const placeholder &other )
const
275 if( type() != other.type() ) {
280 &other_held =
dynamic_cast<const holder<ValueType>&
>(other).held;
281 return ::Teuchos::compare<ValueType>{}(held, other_held);
284 void print(std::ostream & os)
const
285 { ::Teuchos::print<ValueType>{}(os, held); }
294 placeholder* access_content()
296 const placeholder* access_content()
const
305 placeholder * content;
315 bad_any_cast(
const std::string msg ) : std::runtime_error(msg) {}
326 template<
typename ValueType>
332 "any_cast<"<<ValueTypeName<<
">(operand): Error, cast to type "
333 <<
"any::holder<"<<ValueTypeName<<
"> failed since the actual underlying type is \'"
334 <<
typeName(*operand.access_content()) <<
"!"
338 ,
"any_cast<"<<ValueTypeName<<
">(operand): Error, cast to type "
339 <<
"any::holder<"<<ValueTypeName<<
"> failed because the content is NULL"
341 any::holder<ValueType>
342 *dyn_cast_content =
dynamic_cast<any::holder<ValueType>*
>(operand.access_content());
344 !dyn_cast_content, std::logic_error
345 ,
"any_cast<"<<ValueTypeName <<
">(operand): Error, cast to type "
346 <<
"any::holder<"<<ValueTypeName<<
"> failed but should not have and the actual underlying type is \'"
347 <<
typeName(*operand.access_content()) <<
"!"
348 <<
" The problem might be related to incompatible RTTI systems in static and shared libraries!"
350 return dyn_cast_content->held;
362 template<
typename ValueType>
365 return any_cast<ValueType>(
const_cast<any&
>(operand));
371 template <
typename ValueType>
372 ValueType* any_cast(
any* operand)
374 return &any_cast<ValueType>(*operand);
380 template <
typename ValueType>
381 ValueType any_cast(any&& operand)
383 using U = std::remove_cv_t<std::remove_reference_t<ValueType>>;
384 static_assert(std::is_constructible_v<ValueType, U>);
385 return static_cast<ValueType
>(std::move(*any_cast<U>(&operand)));
395 template<
typename ValueType>
398 return Teuchos::any_cast<ValueType>(operand);
408 std::ostringstream oss;
454 template <
typename T>
458 return any_cast<T>(rhs);
463 #endif // TEUCHOS_ANY_HPP
void print(std::ostream &os) const
Print this value to the output stream os
TEUCHOS_DEPRECATED bool empty() const
Return true if nothing is being stored.
T & make_any_ref(any &rhs)
Default constructs a new T value and returns a reference to it.
bool same(const any &other) const
Return if two any objects are the same or not.
ValueType & any_cast(any &operand)
Used to extract the templated value held in Teuchos::any to a given value type.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
bool has_value() const
Checks whether the object contains a value.
TEUCHOSCORE_LIB_DLL_EXPORT std::string demangleName(const std::string &mangledName)
Demangle a C++ name if valid.
const ValueType & any_cast(const any &operand)
Used to extract the const templated value held in Teuchos::any to a given const value type...
Modified boost::any class, which is a container for a templated value.
any & swap(any &rhs)
Method for swapping the contents of two any classes.
std::string toString(const any &rhs)
Converts the value in any to a std::string.
Thrown if any_cast is attempted between two incompatable types.
ValueType & any_ref_cast(any &operand)
Keep the convenient behavior of Teuchos::any_cast w.r.t. references, but don't confuse it with the be...
any & operator=(const ValueType &rhs)
Copy the value rhs
any(ValueType &&value)
Templated constructor.
bool operator==(const any &a, const any &b)
Returns true if two any objects have the same value.
std::string typeName() const
Return the name of the type.
any & operator=(any &&other)
Move-assignment operator.
const std::type_info & type() const
Return the type of value being stored.
bool operator!=(const any &a, const any &b)
Returns true if two any objects do not have the same value.
void swap(Teuchos::any &a, Teuchos::any &b)
Special swap for other code to find via Argument Dependent Lookup.
Defines basic traits returning the name of a type in a portable and readable way. ...
any & operator=(const any &rhs)
Copy the value held in rhs
any(any &&other)
Move constructor.
static std::string name()
any(const any &other)
Copy constructor.
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
std::ostream & operator<<(std::ostream &os, const any &rhs)
Writes "any" input rhs to the output stream os.
#define TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.