]> gitweb.ps.run Git - toc/blobdiff - 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
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/support/Any.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/support/Any.h
new file mode 100644 (file)
index 0000000..468db98
--- /dev/null
@@ -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