diff options
Diffstat (limited to 'antlr4-cpp-runtime-4.9.2-source/install/include/antlr4-runtime/support/Any.h')
| -rw-r--r-- | antlr4-cpp-runtime-4.9.2-source/install/include/antlr4-runtime/support/Any.h | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/antlr4-cpp-runtime-4.9.2-source/install/include/antlr4-runtime/support/Any.h b/antlr4-cpp-runtime-4.9.2-source/install/include/antlr4-runtime/support/Any.h new file mode 100644 index 0000000..468db98 --- /dev/null +++ b/antlr4-cpp-runtime-4.9.2-source/install/include/antlr4-runtime/support/Any.h @@ -0,0 +1,170 @@ +/* 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 |
