/usr/include/libint2/util/any.h is in libint2-dev 2.3.0~beta3-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | // taken from http://codereview.stackexchange.com/questions/20058/c11-any-class
// and modified slightly.
// this code is in public domain
#ifndef _libint2_include_libint2_util_any_h_
#define _libint2_include_libint2_util_any_h_
#include <type_traits>
#include <utility>
#include <typeinfo>
#include <string>
#include <cassert>
namespace libint2 {
/// emulates boost::any
struct any
{
public:
template<class T>
using StorageType = typename std::decay<T>::type;
/// constructs a default any object which evaluates to false
any() = default;
any(const any& that) : handle_(that.clone()) {}
any(any&& that) : handle_(std::move(that.handle_)) { }
template <typename U,
typename = typename std::enable_if<not std::is_same<
any, typename std::decay<U>::type>::value>::type>
any(U&& value)
: handle_(new handle<StorageType<U>>(std::forward<U>(value))) {}
any& operator=(const any& a)
{
any tmp(a);
std::swap(*this, tmp);
return *this;
}
template <typename U,
typename = typename std::enable_if<not std::is_same<
any, typename std::decay<U>::type>::value>::type>
any& operator=(U a) {
any tmp(std::forward<U>(a));
std::swap(*this, tmp);
return *this;
}
any& operator=(any&& a) {
std::swap(handle_, a.handle_);
return *this;
}
bool empty() const { return handle_ == nullptr; }
template<class U> bool is() const
{
typedef StorageType<U> T;
auto derived = dynamic_cast<handle<T>*> (handle_.get());
return derived;
}
/// \note if NDEBUG is not defined, will throw \c std::bad_cast if U is not the stored type
template<class U>
StorageType<U>& as()
{
typedef StorageType<U> T;
#if not defined(NDEBUG)
auto derived = dynamic_cast<handle<T>*> (handle_.get());
if (!derived)
throw std::bad_cast();
#else // NDEBUG
auto derived = static_cast<handle<T>*> (handle_.get());
#endif
return derived->value;
}
/// \note if NDEBUG is not defined, will throw \c std::bad_cast if U is not the stored type
template<class U>
const StorageType<U>& as() const
{
typedef StorageType<U> T;
#if not defined(NDEBUG)
auto derived = dynamic_cast<handle<T>*> (handle_.get());
if (!derived)
throw std::bad_cast();
#else // NDEBUG
auto derived = static_cast<handle<T>*> (handle_.get());
#endif
return derived->value;
}
template<class U>
explicit operator U()
{
return as<StorageType<U>>();
}
private:
struct handle_base
{
virtual ~handle_base() {}
virtual handle_base* clone() const = 0;
};
template<typename T>
struct handle : handle_base
{
template<typename U> handle(U&& value) : value(std::forward<U>(value)) { }
T value;
handle_base* clone() const { return new handle<T>(value); }
};
handle_base* clone() const
{
if (handle_)
return handle_->clone();
else
return nullptr;
}
std::unique_ptr<handle_base> handle_;
};
} // namespace libint2
#endif // header guard
|