]> gitweb.ps.run Git - toc/blob - antlr4-cpp-runtime-4.9.2-source/runtime/src/support/Any.h
add antlr source code and ReadMe
[toc] / antlr4-cpp-runtime-4.9.2-source / runtime / src / support / Any.h
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.
4  */
5
6 // A standard C++ class loosely modeled after boost::Any.
7
8 #pragma once
9
10 #include "antlr4-common.h"
11
12 #ifdef _MSC_VER
13   #pragma warning(push)
14   #pragma warning(disable: 4521) // 'antlrcpp::Any': multiple copy constructors specified
15 #endif
16
17 namespace antlrcpp {
18
19 template<class T>
20   using StorageType = typename std::decay<T>::type;
21
22 struct ANTLR4CPP_PUBLIC Any
23 {
24   bool isNull() const { return _ptr == nullptr; }
25   bool isNotNull() const { return _ptr != nullptr; }
26
27   Any() : _ptr(nullptr) {
28   }
29
30   Any(Any& that) : _ptr(that.clone()) {
31   }
32
33   Any(Any&& that) : _ptr(that._ptr) {
34     that._ptr = nullptr;
35   }
36
37   Any(const Any& that) : _ptr(that.clone()) {
38   }
39
40   Any(const Any&& that) : _ptr(that.clone()) {
41   }
42
43   template<typename U>
44   Any(U&& value) : _ptr(new Derived<StorageType<U>>(std::forward<U>(value))) {
45   }
46
47   template<class U>
48   bool is() const {
49     auto derived = getDerived<U>(false);
50
51     return derived != nullptr;
52   }
53
54   template<class U>
55   StorageType<U>& as() {
56     auto derived = getDerived<U>(true);
57
58     return derived->value;
59   }
60
61   template<class U>
62   const StorageType<U>& as() const {
63     auto derived = getDerived<U>(true);
64
65     return derived->value;
66   }
67
68   template<class U>
69   operator U() {
70     return as<StorageType<U>>();
71   }
72
73   template<class U>
74   operator const U() const {
75     return as<const StorageType<U>>();
76   }
77
78   Any& operator = (const Any& a) {
79     if (_ptr == a._ptr)
80       return *this;
81
82     auto * old_ptr = _ptr;
83     _ptr = a.clone();
84
85     if (old_ptr)
86       delete old_ptr;
87
88     return *this;
89   }
90
91   Any& operator = (Any&& a) {
92     if (_ptr == a._ptr)
93       return *this;
94
95     std::swap(_ptr, a._ptr);
96
97     return *this;
98   }
99
100   virtual ~Any();
101
102   virtual bool equals(Any other) const {
103     return _ptr == other._ptr;
104   }
105
106 private:
107   struct Base {
108     virtual ~Base() {};
109     virtual Base* clone() const = 0;
110   };
111
112   template<typename T>
113   struct Derived : Base
114   {
115     template<typename U> Derived(U&& value_) : value(std::forward<U>(value_)) {
116     }
117
118     T value;
119
120     Base* clone() const {
121       return clone<>();
122     }
123
124   private:
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);
128     }
129
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 {
132       return nullptr;
133     }
134
135   };
136
137   Base* clone() const
138   {
139     if (_ptr)
140       return _ptr->clone();
141     else
142       return nullptr;
143   }
144
145   template<class U>
146   Derived<StorageType<U>>* getDerived(bool checkCast) const {
147     typedef StorageType<U> T;
148
149     auto derived = dynamic_cast<Derived<T>*>(_ptr);
150
151     if (checkCast && !derived)
152       throw std::bad_cast();
153
154     return derived;
155   }
156
157   Base *_ptr;
158
159 };
160
161   template<> inline
162   Any::Any(std::nullptr_t&& ) : _ptr(nullptr) {
163   }
164
165
166 } // namespace antlrcpp
167
168 #ifdef _MSC_VER
169 #pragma warning(pop)
170 #endif