added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / util / type_traits.hpp
diff --git a/iOS/Pods/Realm/include/core/realm/util/type_traits.hpp b/iOS/Pods/Realm/include/core/realm/util/type_traits.hpp
new file mode 100644 (file)
index 0000000..cedbe05
--- /dev/null
@@ -0,0 +1,161 @@
+/*************************************************************************
+ *
+ * Copyright 2016 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_TYPE_TRAITS_HPP
+#define REALM_UTIL_TYPE_TRAITS_HPP
+
+#include <cstdint>
+#include <climits>
+#include <cwchar>
+#include <limits>
+#include <type_traits>
+
+#include <realm/util/features.h>
+#include <realm/util/assert.hpp>
+#include <realm/util/type_list.hpp>
+
+namespace realm {
+namespace util {
+
+template <class From, class To>
+struct CopyConst {
+private:
+    typedef typename std::remove_const<To>::type type_1;
+
+public:
+    typedef typename std::conditional<std::is_const<From>::value, const type_1, type_1>::type type;
+};
+
+
+/// Member `type` is the type resulting from integral or
+/// floating-point promotion of a value of type `T`.
+///
+/// \note Enum types are supported only when the compiler supports the
+/// C++11 'decltype' feature.
+template <class T>
+struct Promote;
+
+
+/// Member `type` is the type of the result of a binary arithmetic (or
+/// bitwise) operation (+, -, *, /, %, |, &, ^) when applied to
+/// operands of type `A` and `B` respectively. The type of the result
+/// of a shift operation (<<, >>) can instead be found as the type
+/// resulting from integral promotion of the left operand. The type of
+/// the result of a unary arithmetic (or bitwise) operation can be
+/// found as the type resulting from integral promotion of the
+/// operand.
+///
+/// \note Enum types are supported only when the compiler supports the
+/// C++11 'decltype' feature.
+template <class A, class B>
+struct ArithBinOpType;
+
+
+/// Member `type` is `B` if `B` has more value bits than `A`,
+/// otherwise is is `A`.
+template <class A, class B>
+struct ChooseWidestInt;
+
+
+/// Member `type` is the first of `unsigned char`, `unsigned short`,
+/// `unsigned int`, `unsigned long`, and `unsigned long long` that has
+/// at least `bits` value bits.
+template <int bits>
+struct LeastUnsigned;
+
+
+/// Member `type` is `unsigned` if `unsigned` has at least `bits`
+/// value bits, otherwise it is the same as
+/// `LeastUnsigned<bits>::%type`.
+template <int bits>
+struct FastestUnsigned;
+
+
+// Implementation
+
+
+template <class T>
+struct Promote {
+    typedef decltype(+T()) type; // FIXME: This is not performing floating-point promotion.
+};
+
+
+template <class A, class B>
+struct ArithBinOpType {
+    typedef decltype(A() + B()) type;
+};
+
+
+template <class A, class B>
+struct ChooseWidestInt {
+private:
+    typedef std::numeric_limits<A> lim_a;
+    typedef std::numeric_limits<B> lim_b;
+    static_assert(lim_a::is_specialized && lim_b::is_specialized,
+                  "std::numeric_limits<> must be specialized for both types");
+    static_assert(lim_a::is_integer && lim_b::is_integer, "Both types must be integers");
+
+public:
+    typedef typename std::conditional<(lim_a::digits >= lim_b::digits), A, B>::type type;
+};
+
+
+template <int bits>
+struct LeastUnsigned {
+private:
+    typedef void types_0;
+    typedef TypeAppend<types_0, unsigned char>::type types_1;
+    typedef TypeAppend<types_1, unsigned short>::type types_2;
+    typedef TypeAppend<types_2, unsigned int>::type types_3;
+    typedef TypeAppend<types_3, unsigned long>::type types_4;
+    typedef TypeAppend<types_4, unsigned long long>::type types_5;
+    typedef types_5 types;
+    // The `dummy<>` template is there to work around a bug in
+    // VisualStudio (seen in versions 2010 and 2012). Without the
+    // `dummy<>` template, The C++ compiler in Visual Studio would
+    // attempt to instantiate `FindType<type, pred>` before the
+    // instantiation of `LeastUnsigned<>` which obviously fails
+    // because `pred` depends on `bits`.
+    template <int>
+    struct dummy {
+        template <class T>
+        struct pred {
+            static const bool value = std::numeric_limits<T>::digits >= bits;
+        };
+    };
+
+public:
+    typedef typename FindType<types, dummy<bits>::template pred>::type type;
+    static_assert(!(std::is_same<type, void>::value), "No unsigned type is that wide");
+};
+
+
+template <int bits>
+struct FastestUnsigned {
+private:
+    typedef typename util::LeastUnsigned<bits>::type least_unsigned;
+
+public:
+    typedef typename util::ChooseWidestInt<unsigned, least_unsigned>::type type;
+};
+
+
+} // namespace util
+} // namespace realm
+
+#endif // REALM_UTIL_TYPE_TRAITS_HPP