added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / util / any.hpp
diff --git a/iOS/Pods/Realm/include/core/realm/util/any.hpp b/iOS/Pods/Realm/include/core/realm/util/any.hpp
new file mode 100644 (file)
index 0000000..90baef8
--- /dev/null
@@ -0,0 +1,161 @@
+////////////////////////////////////////////////////////////////////////////
+//
+// Copyright 2017 Realm Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef REALM_UTIL_ANY_HPP
+#define REALM_UTIL_ANY_HPP
+
+#include <memory>
+#include <stdexcept>
+#include <type_traits>
+#include <typeinfo>
+
+namespace realm {
+namespace util {
+
+// A naive implementation of C++17's std::any
+// This does not perform the small-object optimization or make any particular
+// attempt at being performant
+class Any final {
+public:
+    // Constructors
+
+    Any() = default;
+    Any(Any&&) noexcept = default;
+    ~Any() = default;
+    Any& operator=(Any&&) noexcept = default;
+
+    Any(Any const& rhs)
+    : m_value(rhs.m_value ? rhs.m_value->copy() : nullptr)
+    {
+    }
+
+    template<typename T, typename = typename std::enable_if<!std::is_same<typename std::decay<T>::type, Any>::value>::type>
+    Any(T&& value)
+    : m_value(std::make_unique<Value<typename std::decay<T>::type>>(std::forward<T>(value)))
+    {
+    }
+
+    Any& operator=(Any const& rhs)
+    {
+        m_value = rhs.m_value ? rhs.m_value->copy() : nullptr;
+        return *this;
+    }
+
+    template<typename T, typename = typename std::enable_if<!std::is_same<typename std::decay<T>::type, Any>::value>::type>
+    Any& operator=(T&& value)
+    {
+        m_value = std::make_unique<Value<typename std::decay<T>::type>>(std::forward<T>(value));
+        return *this;
+    }
+
+    // Modifiers
+
+    void reset() noexcept { m_value.reset(); }
+    void swap(Any& rhs) noexcept { std::swap(m_value, rhs.m_value); }
+
+    // Observers
+
+    bool has_value() const noexcept { return m_value != nullptr; }
+    std::type_info const& type() const noexcept { return m_value ? m_value->type() : typeid(void); }
+
+private:
+    struct ValueBase {
+        virtual ~ValueBase() noexcept { }
+        virtual std::type_info const& type() const noexcept = 0;
+        virtual std::unique_ptr<ValueBase> copy() const = 0;
+    };
+    template<typename T>
+    struct Value : ValueBase {
+        T value;
+        template<typename U> Value(U&& v) : value(std::forward<U>(v)) { }
+
+        std::type_info const& type() const noexcept override { return typeid(T); }
+        std::unique_ptr<ValueBase> copy() const override
+        {
+            return std::make_unique<Value<T>>(value);
+        }
+    };
+    std::unique_ptr<ValueBase> m_value;
+
+    template<typename T>
+    friend const T* any_cast(const Any* operand) noexcept;
+    template<typename T>
+    friend T* any_cast(Any* operand) noexcept;
+
+    template<typename T>
+    const T* cast() const noexcept
+    {
+        return &static_cast<Value<T>*>(m_value.get())->value;
+    }
+
+    template<typename T>
+    T* cast() noexcept
+    {
+        return &static_cast<Value<T>*>(m_value.get())->value;
+    }
+};
+
+template<typename T>
+T any_cast(Any const& value)
+{
+    auto ptr = any_cast<typename std::add_const<typename std::remove_reference<T>::type>::type>(&value);
+    if (!ptr)
+        throw std::bad_cast();
+    return *ptr;
+}
+
+template<typename T>
+T any_cast(Any& value)
+{
+    auto ptr = any_cast<typename std::remove_reference<T>::type>(&value);
+    if (!ptr)
+        throw std::bad_cast();
+    return *ptr;
+}
+
+template<typename T>
+T any_cast(Any&& value)
+{
+    auto ptr = any_cast<typename std::remove_reference<T>::type>(&value);
+    if (!ptr)
+        throw std::bad_cast();
+    return std::move(*ptr);
+}
+
+template<typename T>
+T* any_cast(Any* value) noexcept
+{
+    return value && value->type() == typeid(T) ? value->cast<T>() : nullptr;
+}
+
+template<typename T>
+const T* any_cast(const Any* value) noexcept
+{
+    return value && value->type() == typeid(T) ? value->cast<T>() : nullptr;
+}
+} // namespace util
+} // namespace realm
+
+namespace std {
+inline void swap(realm::util::Any& lhs, realm::util::Any& rhs) noexcept
+{
+    lhs.swap(rhs);
+}
+} // namespace std
+
+#endif // REALM_UTIL_ANY_HPP