Bifrost SDK
Bifrost SDK documentation
Any.h
Go to the documentation of this file.
1//-
2// =============================================================================
3// Copyright 2025 Autodesk, Inc. All rights reserved.
4//
5// Use of this software is subject to the terms of the Autodesk license
6// agreement provided at the time of installation or download, or which
7// otherwise accompanies this software in either electronic or hard copy form.
8// =============================================================================
9//+
10
16
17#ifndef AMINO_ANY_H
18#define AMINO_ANY_H
19
20//==============================================================================
21// EXTERNAL DECLARATIONS
22//==============================================================================
23
24#include "internal/AnyImpl.h"
25
26namespace Amino {
27class StringView;
28
29//==============================================================================
30// CLASS AnyPayloadTraits
31//==============================================================================
32
38private:
46 template <typename T>
47 struct is_amino_array : std::false_type {};
48 template <typename T>
49 struct is_amino_array<Amino::Array<T>> : std::true_type {};
51
52 template <bool Bool>
53 using bool_t = std::integral_constant<bool, Bool>;
54
55public:
57 template <typename ValueType, typename T = std::decay_t<ValueType>>
58 using is_cast_enabled = bool_t<(
59 // The payload must not be an Any.
60 !std::is_same<Any, T>::value &&
61
62 // The payload should not be an Amino::Array directly.
63 // Need to be wrapped in an Amino::Ptr (i.e. Ptr<Array<T>>).
64 !is_amino_array<T>::value &&
65
66 // Must not be Amino::StringView.
67 // This is almost certainly a programming error since StringView
68 // is not value semantics. Most likely need to store a String instead.
69 !std::is_same<Amino::StringView, T>::value &&
70
71 // Must not be raw pointer type.
72 !std::is_pointer<T>::value &&
73
74 // Must not be raw array type.
75 !std::is_array<ValueType>::value &&
76 !std::is_array<std::remove_reference_t<ValueType>>::value)>;
77
80 template <typename ValueType, typename T = std::decay_t<ValueType>>
81 using is_valid = bool_t<(
82 // The type must be queriable
84
85 // Must be copy constructible (to allow copying
86 // the Any with such payload).
87 std::is_copy_constructible<T>::value &&
88
89 // Must be standard layout.
90 std::is_standard_layout<T>::value)>;
91
93 template <typename ValueType>
94 using enable_if_valid = std::enable_if_t<is_valid<ValueType>::value>;
95
97 template <typename ValueType, typename... Args>
98 using enable_if_constructible = std::enable_if_t<
99 std::is_constructible<std::decay_t<ValueType>, Args...>::value>;
100};
101
102//==============================================================================
103// CLASS Any
104//==============================================================================
105
106//------------------------------------------------------------------------------
180class Any : private Internal::AnyImpl::AnyUntyped {
181 using Base = Internal::AnyImpl::AnyUntyped;
182 using Traits = AnyPayloadTraits;
183
184public:
190 Any() noexcept = default;
191
200 Any(Any const& other) = default;
201
208 Any(Any&& other) noexcept = default;
209
220 template <typename ValueType, typename = Traits::enable_if_valid<ValueType>>
221 explicit Any(ValueType&& v) noexcept : Base(std::forward<ValueType>(v)) {}
222
226 ~Any() = default;
227
232 Any& operator=(Any const& rhs) = default;
233
242 Any& operator=(Any&& rhs) noexcept = default;
243
252 template <typename ValueType, typename = Traits::enable_if_valid<ValueType>>
253 Any& operator=(ValueType&& rhs) & noexcept {
254 Any(std::forward<ValueType>(rhs)).swap(*this);
255 return *this;
256 }
257
272 template <
273 typename ValueType,
274 typename... Args,
275 typename = Traits::enable_if_valid<ValueType>,
276 typename = Traits::enable_if_constructible<ValueType, Args...>>
277 void emplace(Args&&... args) noexcept {
278 Base::emplace<ValueType>(std::forward<Args>(args)...);
279 }
280
295 template <
296 typename ValueType,
297 typename Up,
298 typename... Args,
299 typename IL = std::initializer_list<Up>,
300 typename = Traits::enable_if_valid<ValueType>,
301 typename = Traits::enable_if_constructible<ValueType, IL&, Args...>>
302 void emplace(std::initializer_list<Up> il, Args&&... args) noexcept {
303 Base::emplace<ValueType>(il, std::forward<Args>(args)...);
304 }
305
311 void reset() noexcept { Base::reset(); }
312
314 Any& swap(Any& rhs) noexcept {
315 Base::swap(*this, rhs);
316 return rhs;
317 }
318
320 bool has_value() const noexcept { return Base::has_value(); }
321
322 AMINO_INTERNAL_DEPRECATED("Use any.type() == other.type() instead.")
323 bool has_same_type(Any const& other) const noexcept {
324 return type() == other.type();
325 }
326
329 TypeId type() const noexcept { return Base::type(); }
330
331private:
333 friend Internal::RuntimeAny;
334 friend Internal::AnyCast;
336};
337
338//------------------------------------------------------------------------------
339//
340// enforce expected layout, size and alignment of Amino::Any
341static_assert(
342 std::is_standard_layout<Any>::value,
343 "Amino::Any must be standard layout. ");
344static_assert(
345 sizeof(Any) == Internal::AnyTraits::sBufferSize + sizeof(void*),
346 "Incorrect Amino::Any size");
347static_assert(
348 alignof(Any) == Internal::AnyTraits::sBufferAlign,
349 "Incorrect Amino::Any alignment");
350
351//==============================================================================
352// NON MEMBER FUNCTIONS
353//==============================================================================
354
355//------------------------------------------------------------------------------
356//
358inline void swap(Any& lhs, Any& rhs) noexcept { lhs.swap(rhs); }
359
360//==============================================================================
361// ANY CAST FUNCTIONS
362//==============================================================================
363
364//------------------------------------------------------------------------------
365//
377template <
378 class ValueType,
379 typename = std::enable_if_t<!std::is_same<void, ValueType>::value>>
380inline std::add_pointer_t<std::add_const_t<ValueType>> any_cast(
381 Any const* v) noexcept {
382 static_assert(
384 "ValueType must be a valid payload type");
385 if (!v) return nullptr; // assert?
386 return Internal::AnyCast::cast<ValueType>(v);
387}
388
389//------------------------------------------------------------------------------
390//
401template <
402 class ValueType,
403 typename = std::enable_if_t<!std::is_same<void, ValueType>::value>>
404inline std::add_pointer_t<ValueType> any_cast(Any* v) noexcept {
405 static_assert(
407 "ValueType must be a valid payload type");
408 if (!v) return nullptr; // assert?
409 return Internal::AnyCast::cast<ValueType>(v);
410}
411
412//------------------------------------------------------------------------------
413//
432template <
433 class ValueType,
434 typename = std::enable_if_t<std::is_same<void, ValueType>::value>>
435AMINO_INTERNAL_DEPRECATED("Use any_cast<ValueType> instead.")
436inline void const* any_cast(Any const* v) noexcept {
437 if (!v) return nullptr; // assert?
438 return Internal::AnyCast::cast<void>(v);
439}
440
441//------------------------------------------------------------------------------
442//
454template <typename ValueType>
455inline ValueType any_cast(Any const& v) noexcept {
456 static_assert(
458 "ValueType must be a valid payload type");
459 using Tp = std::add_const_t<std::remove_reference_t<ValueType>>;
460 Tp* tmp = any_cast<Tp>(&v);
461 return tmp ? *tmp : ValueType();
462}
463
464//------------------------------------------------------------------------------
465//
480template <typename ValueType>
481inline ValueType any_cast(Any&& v) noexcept {
482 static_assert(
484 "ValueType must be a valid payload type");
485 using Tp = std::add_const_t<std::remove_reference_t<ValueType>>;
486 Any any{std::move(v)};
487 Tp* tmp = any_cast<Tp>(&any);
488 return tmp ? std::move(*tmp) : ValueType();
489}
490
491} // namespace Amino
492
493#endif
Definition: HostData.h:33
std::add_pointer_t< std::add_const_t< ValueType > > any_cast(Any const *v) noexcept
Cast an instance of Any to a payload type.
Definition: Any.h:380
AMINO_INTERNAL_DEPRECATED("Amino::isJobCancelled is deprecated and now always returns false. " "Use a 'StopToken const& jobport instead. ") inline bool isJobCancelled()
Definition: Cancellation.h:30
void swap(Any &lhs, Any &rhs) noexcept
Swap the payloads of two instances of Any.
Definition: Any.h:358
Definition: Ptr.h:2080
Traits about the to-be-payload of an Amino::Any.
Definition: Any.h:37
bool_t<(!std::is_same< Any, T >::value &&!is_amino_array< T >::value &&!std::is_same< Amino::StringView, T >::value &&!std::is_pointer< T >::value &&!std::is_array< ValueType >::value &&!std::is_array< std::remove_reference_t< ValueType > >::value)> is_cast_enabled
Whether a Any can be queried to extract its payload as type T.
Definition: Any.h:76
std::enable_if_t< is_valid< ValueType >::value > enable_if_valid
Enable if the type is a valid payload type.
Definition: Any.h:94
std::enable_if_t< std::is_constructible< std::decay_t< ValueType >, Args... >::value > enable_if_constructible
Enable if the type can be constructed from the given arguments.
Definition: Any.h:99
bool_t<(is_cast_enabled< ValueType >::value &&std::is_copy_constructible< T >::value &&std::is_standard_layout< T >::value)> is_valid
Whether a type T is a valid payload type. (i.e. can be assigned in an Any).
Definition: Any.h:90
Generic value class that allows for storage of a value of any type.
Definition: Any.h:180
AMINO_INTERNAL_DEPRECATED("Use any.type() == other.type() instead.") bool has_same_type(Any const &other) const noexcept
Definition: Any.h:322
Any & swap(Any &rhs) noexcept
Swap payloads with another Any object.
Definition: Any.h:314
Any & operator=(Any &&rhs) noexcept=default
Move assignment operator.
void emplace(Args &&... args) noexcept
Replaces the contained object of this Any.
Definition: Any.h:277
Any & operator=(ValueType &&rhs) &noexcept
Move assignment conversion.
Definition: Any.h:253
Any & operator=(Any const &rhs)=default
Copy assignment operator.
void emplace(std::initializer_list< Up > il, Args &&... args) noexcept
Replaces the contained object of this Any.
Definition: Any.h:302
void reset() noexcept
Reset this Any object.
Definition: Any.h:311
~Any()=default
Destructor.
bool has_value() const noexcept
Return true if this Any object contains a payload.
Definition: Any.h:320
TypeId type() const noexcept
Returns the TypeId of the value in this Any, or the TypeId of void if this Any does not have a value.
Definition: Any.h:329
Any() noexcept=default
Default constructor.
Define a Amino array of elements of type T.
Definition: Array.h:105
Type identifier for a type.
Definition: TypeId.h:45