21 #ifndef _libint2_include_libint2_util_any_h_ 22 #define _libint2_include_libint2_util_any_h_ 24 #include <type_traits> 31 #if __cplusplus >= 201703L 34 # if defined(_LIBCPP_VERSION) && defined(__APPLE__) 35 # include <Availability.h> 36 # ifdef __MAC_OS_X_VERSION_MIN_ALLOWED 37 # if __MAC_OS_X_VERSION_MIN_ALLOWED >= 10140 38 # define LIBINT_HAS_CXX17_ANY 39 # endif // 10.14 or later 40 # endif // have macos version 41 # else // libc++ on macos 42 # define LIBINT_HAS_CXX17_ANY 43 # endif // libc++ on macos 46 #ifdef LIBINT_HAS_CXX17_ANY 53 #ifdef LIBINT_HAS_CXX17_ANY 56 using std::bad_any_cast;
61 template <
typename Base,
typename T>
62 using disable_if_same_or_derived =
typename std::enable_if<
63 !std::is_base_of<Base, typename std::decay<T>::type>::value>::type;
70 any() : impl_(
nullptr) {}
71 any(
const any& other) : impl_(other.impl_->clone()) {}
72 any(
any&& other) =
default;
73 template <
typename ValueType,
74 typename = detail::disable_if_same_or_derived<any, ValueType> >
75 any(ValueType&& value)
76 : impl_(
new impl<
typename std::decay<ValueType>::type>(
77 std::forward<ValueType>(value))) {}
80 any& operator=(
const any& rhs ) {
81 impl_ = decltype(impl_)(rhs.impl_->clone());
84 any& operator=(
any&& rhs ) {
85 impl_ = std::move(rhs.impl_);
88 template <
typename ValueType,
89 typename = detail::disable_if_same_or_derived<any, ValueType> >
90 any& operator=(ValueType&& rhs) {
91 impl_ = decltype(impl_)(
new impl<typename std::decay<ValueType>::type>(
92 std::forward<ValueType>(rhs)));
96 template<
class ValueType,
class... Args >
97 typename std::decay<ValueType>::type& emplace( Args&&... args ) {
99 impl_ =
new impl<typename std::decay<ValueType>::type> (
100 std::forward<Args>(args)...);
101 return (impl_->cast_static<
typename std::decay<ValueType>::type>()->value);
103 template<
class ValueType,
class U,
class... Args >
104 typename std::decay<ValueType>::type& emplace( std::initializer_list<U> il, Args&&... args ) {
106 impl_ =
new impl<typename std::decay<ValueType>::type> (il,
107 std::forward<Args>(args)...);
108 return (impl_->cast_static<
typename std::decay<ValueType>::type>()->value);
111 void reset() { impl_.reset(); }
113 void swap(
any& other) {
114 std::swap(impl_, other.impl_);
117 bool has_value()
const {
118 return static_cast<bool>(impl_);
121 const std::type_info& type()
const {
123 return impl_->type();
129 template <
typename T>
struct impl;
132 virtual ~impl_base() {}
133 virtual impl_base* clone()
const = 0;
135 virtual const std::type_info& type()
const = 0;
138 template <
typename T> impl<T>* cast() {
140 return this->cast_static<T>();
142 return dynamic_cast<impl<T>*
>(
this);
146 template <
typename T> impl<T>* cast_static() {
147 return static_cast<impl<T>*
>(
this);
150 template <
typename T>
151 struct impl :
public impl_base {
152 template <
typename U>
explicit impl(U&& v) : value(std::forward<U>(v)) {}
153 impl_base* clone()
const override {
154 return new impl{value};
157 const std::type_info& type()
const override {
164 template<
typename ValueType>
165 friend typename std::decay<ValueType>::type* any_cast(
any* operand);
166 template<
typename ValueType>
167 friend const typename std::decay<ValueType>::type* any_cast(
const any* operand);
169 template <
typename ValueType>
170 typename std::decay<ValueType>::type* value_ptr() {
171 return &(impl_->cast_static<
typename std::decay<ValueType>::type>()->value);
174 template <
typename ValueType>
175 const typename std::decay<ValueType>::type* value_ptr()
const {
176 return &(impl_->cast_static<
typename std::decay<ValueType>::type>()->value);
179 std::unique_ptr<impl_base> impl_;
186 virtual const char* what()
const noexcept {
187 return "Bad any_cast";
191 template<
typename ValueType>
192 typename std::decay<ValueType>::type* any_cast(
any* operand) {
193 if (operand->type() ==
typeid(
typename std::decay<ValueType>::type))
194 return operand->value_ptr<
typename std::decay<ValueType>::type>();
199 template<
typename ValueType>
200 const typename std::decay<ValueType>::type* any_cast(
const any* operand) {
201 if (operand->type() ==
typeid(
typename std::decay<ValueType>::type))
202 return operand->value_ptr<
typename std::decay<ValueType>::type>();
207 template <
typename ValueType>
208 ValueType any_cast(
const any& operand) {
209 const auto* cast_ptr =
210 any_cast<
typename std::decay<ValueType>::type>(&operand);
211 if (cast_ptr !=
nullptr)
return *cast_ptr;
212 throw bad_any_cast();
215 template <
typename ValueType>
216 ValueType any_cast(any& operand) {
217 auto* cast_ptr = any_cast<
typename std::decay<ValueType>::type>(&operand);
218 if (cast_ptr !=
nullptr)
return *cast_ptr;
219 throw bad_any_cast();
225 #endif // header guard Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24
a partial C++17 std::any implementation (and less efficient than can be)
Definition: any.h:67