1 /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
2 * Use of this file is governed by the BSD 3-clause license that
3 * can be found in the LICENSE.txt file in the project root.
6 // A standard C++ class loosely modeled after boost::Any.
10 #include "antlr4-common.h"
14 #pragma warning(disable: 4521) // 'antlrcpp::Any': multiple copy constructors specified
20 using StorageType = typename std::decay<T>::type;
22 struct ANTLR4CPP_PUBLIC Any
24 bool isNull() const { return _ptr == nullptr; }
25 bool isNotNull() const { return _ptr != nullptr; }
27 Any() : _ptr(nullptr) {
30 Any(Any& that) : _ptr(that.clone()) {
33 Any(Any&& that) : _ptr(that._ptr) {
37 Any(const Any& that) : _ptr(that.clone()) {
40 Any(const Any&& that) : _ptr(that.clone()) {
44 Any(U&& value) : _ptr(new Derived<StorageType<U>>(std::forward<U>(value))) {
49 auto derived = getDerived<U>(false);
51 return derived != nullptr;
55 StorageType<U>& as() {
56 auto derived = getDerived<U>(true);
58 return derived->value;
62 const StorageType<U>& as() const {
63 auto derived = getDerived<U>(true);
65 return derived->value;
70 return as<StorageType<U>>();
74 operator const U() const {
75 return as<const StorageType<U>>();
78 Any& operator = (const Any& a) {
82 auto * old_ptr = _ptr;
91 Any& operator = (Any&& a) {
95 std::swap(_ptr, a._ptr);
102 virtual bool equals(Any other) const {
103 return _ptr == other._ptr;
109 virtual Base* clone() const = 0;
113 struct Derived : Base
115 template<typename U> Derived(U&& value_) : value(std::forward<U>(value_)) {
120 Base* clone() const {
125 template<int N = 0, typename std::enable_if<N == N && std::is_nothrow_copy_constructible<T>::value, int>::type = 0>
126 Base* clone() const {
127 return new Derived<T>(value);
130 template<int N = 0, typename std::enable_if<N == N && !std::is_nothrow_copy_constructible<T>::value, int>::type = 0>
131 Base* clone() const {
140 return _ptr->clone();
146 Derived<StorageType<U>>* getDerived(bool checkCast) const {
147 typedef StorageType<U> T;
149 auto derived = dynamic_cast<Derived<T>*>(_ptr);
151 if (checkCast && !derived)
152 throw std::bad_cast();
162 Any::Any(std::nullptr_t&& ) : _ptr(nullptr) {
166 } // namespace antlrcpp