--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+// A standard C++ class loosely modeled after boost::Any.
+
+#pragma once
+
+#include "antlr4-common.h"
+
+#ifdef _MSC_VER
+ #pragma warning(push)
+ #pragma warning(disable: 4521) // 'antlrcpp::Any': multiple copy constructors specified
+#endif
+
+namespace antlrcpp {
+
+template<class T>
+ using StorageType = typename std::decay<T>::type;
+
+struct ANTLR4CPP_PUBLIC Any
+{
+ bool isNull() const { return _ptr == nullptr; }
+ bool isNotNull() const { return _ptr != nullptr; }
+
+ Any() : _ptr(nullptr) {
+ }
+
+ Any(Any& that) : _ptr(that.clone()) {
+ }
+
+ Any(Any&& that) : _ptr(that._ptr) {
+ that._ptr = nullptr;
+ }
+
+ Any(const Any& that) : _ptr(that.clone()) {
+ }
+
+ Any(const Any&& that) : _ptr(that.clone()) {
+ }
+
+ template<typename U>
+ Any(U&& value) : _ptr(new Derived<StorageType<U>>(std::forward<U>(value))) {
+ }
+
+ template<class U>
+ bool is() const {
+ auto derived = getDerived<U>(false);
+
+ return derived != nullptr;
+ }
+
+ template<class U>
+ StorageType<U>& as() {
+ auto derived = getDerived<U>(true);
+
+ return derived->value;
+ }
+
+ template<class U>
+ const StorageType<U>& as() const {
+ auto derived = getDerived<U>(true);
+
+ return derived->value;
+ }
+
+ template<class U>
+ operator U() {
+ return as<StorageType<U>>();
+ }
+
+ template<class U>
+ operator const U() const {
+ return as<const StorageType<U>>();
+ }
+
+ Any& operator = (const Any& a) {
+ if (_ptr == a._ptr)
+ return *this;
+
+ auto * old_ptr = _ptr;
+ _ptr = a.clone();
+
+ if (old_ptr)
+ delete old_ptr;
+
+ return *this;
+ }
+
+ Any& operator = (Any&& a) {
+ if (_ptr == a._ptr)
+ return *this;
+
+ std::swap(_ptr, a._ptr);
+
+ return *this;
+ }
+
+ virtual ~Any();
+
+ virtual bool equals(Any other) const {
+ return _ptr == other._ptr;
+ }
+
+private:
+ struct Base {
+ virtual ~Base() {};
+ virtual Base* clone() const = 0;
+ };
+
+ template<typename T>
+ struct Derived : Base
+ {
+ template<typename U> Derived(U&& value_) : value(std::forward<U>(value_)) {
+ }
+
+ T value;
+
+ Base* clone() const {
+ return clone<>();
+ }
+
+ private:
+ template<int N = 0, typename std::enable_if<N == N && std::is_nothrow_copy_constructible<T>::value, int>::type = 0>
+ Base* clone() const {
+ return new Derived<T>(value);
+ }
+
+ template<int N = 0, typename std::enable_if<N == N && !std::is_nothrow_copy_constructible<T>::value, int>::type = 0>
+ Base* clone() const {
+ return nullptr;
+ }
+
+ };
+
+ Base* clone() const
+ {
+ if (_ptr)
+ return _ptr->clone();
+ else
+ return nullptr;
+ }
+
+ template<class U>
+ Derived<StorageType<U>>* getDerived(bool checkCast) const {
+ typedef StorageType<U> T;
+
+ auto derived = dynamic_cast<Derived<T>*>(_ptr);
+
+ if (checkCast && !derived)
+ throw std::bad_cast();
+
+ return derived;
+ }
+
+ Base *_ptr;
+
+};
+
+ template<> inline
+ Any::Any(std::nullptr_t&& ) : _ptr(nullptr) {
+ }
+
+
+} // namespace antlrcpp
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif