1#ifndef HALCHECK_LIB_ANY_HPP
2#define HALCHECK_LIB_ANY_HPP
11#include <halcheck/lib/type_traits.hpp>
12#include <halcheck/lib/typeinfo.hpp>
13#include <halcheck/lib/variant.hpp>
20namespace halcheck {
namespace lib {
24template<typename T, HALCHECK_REQUIRE(!std::is_void<T>())>
27template<typename T, HALCHECK_REQUIRE(!std::is_void<T>())>
28const T *
any_cast(
const any *operand)
noexcept;
37 constexpr any()
noexcept =
default;
39 any(
const any &other) : _type(other._type), _impl(other.has_value() ? other._impl->clone() :
nullptr) {}
41 any(
any &&other)
noexcept(
false) : _type(other._type), _impl(other.has_value() ? other._impl->move() :
nullptr) {}
55 explicit any(lib::in_place_type_t<T>, Args &&...args)
69 any &operator=(
const any &rhs) {
74 any &operator=(
any &&rhs)
noexcept {
83 any &operator=(T &&rhs)
noexcept {
93 T &emplace(Args &&...args) {
107 void reset()
noexcept {
112 void swap(
any &other)
noexcept {
114 swap(_type, other._type);
115 swap(_impl, other._impl);
118 bool has_value()
const noexcept {
return bool(_impl); }
123 template<typename T, HALCHECK_REQUIRE_(!std::is_void<T>())>
124 friend const T *any_cast(
const any *operand)
noexcept;
126 template<typename T, HALCHECK_REQUIRE_(!std::is_void<T>())>
127 friend T *any_cast(
any *operand)
noexcept;
129 friend void swap(
any &lhs,
any &rhs)
noexcept { lhs.swap(rhs); }
133 virtual const void *data()
const = 0;
134 virtual void *data() = 0;
140 struct derived : base {
141 template<
typename... Args>
144 const void *data()
const override {
return std::addressof(value); }
166 const char *what()
const noexcept override {
return "halcheck::lib::bad_any_cast"; }
175template<
typename T, HALCHECK_REQUIRE(std::is_constructible<T, const lib::remove_cv_t<lib::remove_reference_t<T>> &>())>
178 return static_cast<T
>(*output);
189template<
typename T, HALCHECK_REQUIRE(std::is_constructible<T, lib::remove_cv_t<lib::remove_reference_t<T>> &>())>
192 return static_cast<T
>(*output);
203template<
typename T, HALCHECK_REQUIRE(std::is_constructible<T, lib::remove_cv_t<lib::remove_reference_t<T>>>())>
206 return static_cast<T
>(std::move(*output));
217template<typename T, HALCHECK_REQUIRE_(!std::is_void<T>())>
220 return reinterpret_cast<const T *
>(operand->_impl->data());
231template<typename T, HALCHECK_REQUIRE_(!std::is_void<T>())>
234 return reinterpret_cast<T *
>(operand->_impl->data());
245template<
typename T,
typename... Args>
An implemenetation of std::any.
Definition any.hpp:35
T any_cast(any &operand)
An implementation of std::any_cast.
Definition any.hpp:190
T any_cast(any &&operand)
An implementation of std::any_cast.
Definition any.hpp:204
T any_cast(const any &operand)
An implementation of std::any_cast.
Definition any.hpp:176
any make_any(Args &&...args)
An implementation of std::make_any.
Definition any.hpp:246
T * any_cast(any *operand) noexcept
An implementation of std::any_cast.
Definition any.hpp:232
const T * any_cast(const any *operand) noexcept
An implementation of std::any_cast.
Definition any.hpp:218
typename std::decay< T >::type decay_t
An implementation of std::decay_t.
Definition type_traits.hpp:101
typename std::remove_cv< T >::type remove_cv_t
An implementation of std::remove_cv_t.
Definition type_traits.hpp:109
typename std::remove_reference< T >::type remove_reference_t
An implementation of std::remove_reference_t.
Definition type_traits.hpp:175
#define HALCHECK_REQUIRE(...)
Expands to a template argument that is only valid if the given argument evaluates to true.
Definition type_traits.hpp:24
An implementation of std::bad_any_cast.
Definition any.hpp:165
Determines if a type is a specialization of a template class.
Definition type_traits.hpp:437
static type_id of()
Gets the unique type identifier associated with the given type.
Definition typeinfo.hpp:86
A runtime type identifier that does not require RTTI.
Definition typeinfo.hpp:65