Skip to content

Commit

Permalink
Define utility class template TypedAny: see code comments
Browse files Browse the repository at this point in the history
(cherry picked from commit 2f76b8e;
modified for Tenacity)
Signed-off-by: Avery King <[email protected]>
  • Loading branch information
Paul-Licameli authored and Avery King committed Nov 20, 2024
1 parent a1d2e4f commit 07b7d1d
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
1 change: 1 addition & 0 deletions libraries/lib-utility/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ set( SOURCES
MemoryStream.h
Observer.cpp
Observer.h
TypedAny.h
)
tenacity_library( lib-utility "${SOURCES}" ""
"" ""
Expand Down
82 changes: 82 additions & 0 deletions libraries/lib-utility/TypedAny.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*!********************************************************************
Tenacity
@file TypedAny.h
@brief Wrapper class for std::any, making type distinctions
Paul Licameli
**********************************************************************/
#ifndef __TENACITY_TYPED_ANY__
#define __TENACITY_TYPED_ANY__

#include <any>
#include <utility>

namespace tenacity {

//! Generates distinct, non-interconvertible types wrapping std::any
/*!
@tparam Tag discriminates generated classes; a "CRTP" parameter
*/
template<typename Tag> class TypedAny
{
public:
//! Constructor with arguments just as for std::any, but it is explicit
template<typename... Args>
explicit TypedAny(Args &&... args)
: mAny(std::forward<Args>(args)...)
{}

TypedAny(const TypedAny&) = default;
TypedAny &operator=(const TypedAny&) = default;
TypedAny(TypedAny&&) = default;
TypedAny &operator=(TypedAny&&) = default;

/*!
@name Pass-through member functions
Supply an imitation of std::any's interface, except for reference-valued
any_cast
@{
*/

template<typename ValueType, typename... Args>
std::decay_t<ValueType> &emplace(Args &&... args)
{
return mAny.emplace<ValueType>(std::forward<Args>(args)...);
}
void reset() noexcept { mAny.reset(); }
void swap(TypedAny &other) noexcept { mAny.swap(other.mAny); }
bool has_value() const noexcept { return mAny.has_value(); }
const std::type_info& type() const noexcept { return mAny.type(); }

//! Like pointer-valued any_cast but a non-static member function
template<typename T>
const T* cast() const noexcept { return std::any_cast<T>(&mAny); }

//! Like pointer-valued any_cast but a non-static member function
template<typename T>
T* cast() noexcept { return std::any_cast<T>(&mAny); }

//! Like make_any but a static member function
template<typename T, typename... Args>
static TypedAny make(Args &&... args)
{
return TypedAny(std::in_place_type<T>, std::forward<Args>(args)...);
}

//! @}

private:
std::any mAny;
};

//! Non-member swap
template<typename Tag>
inline void swap(TypedAny<Tag> &x, TypedAny<Tag> &y) { x.swap(y); }

}

#endif

0 comments on commit 07b7d1d

Please sign in to comment.