added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / query_conditions.hpp
diff --git a/iOS/Pods/Realm/include/core/realm/query_conditions.hpp b/iOS/Pods/Realm/include/core/realm/query_conditions.hpp
new file mode 100644 (file)
index 0000000..e4f589d
--- /dev/null
@@ -0,0 +1,801 @@
+/*************************************************************************
+ *
+ * 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_QUERY_CONDITIONS_HPP
+#define REALM_QUERY_CONDITIONS_HPP
+
+#include <cstdint>
+#include <string>
+
+#include <realm/unicode.hpp>
+#include <realm/binary_data.hpp>
+#include <realm/utilities.hpp>
+
+namespace realm {
+
+// Array::VTable only uses the first 4 conditions (enums) in an array of function pointers
+enum { cond_Equal, cond_NotEqual, cond_Greater, cond_Less, cond_VTABLE_FINDER_COUNT, cond_None, cond_LeftNotNull };
+
+// Quick hack to make "Queries with Integer null columns" able to compile in Visual Studio 2015 which doesn't full
+// support sfinae
+// (real cause hasn't been investigated yet, cannot exclude that we don't obey c++11 standard)
+struct HackClass {
+    template <class A, class B, class C>
+    bool can_match(A, B, C)
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    template <class A, class B, class C>
+    bool will_match(A, B, C)
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+};
+
+// Does v2 contain v1?
+struct Contains : public HackClass {
+    bool operator()(StringData v1, const char*, const char*, StringData v2, bool = false, bool = false) const
+    {
+        return v2.contains(v1);
+    }
+    bool operator()(StringData v1, StringData v2, bool = false, bool = false) const
+    {
+        return v2.contains(v1);
+    }
+    bool operator()(BinaryData v1, BinaryData v2, bool = false, bool = false) const
+    {
+        return v2.contains(v1);
+    }
+    bool operator()(StringData v1, const std::array<uint8_t, 256> &charmap, StringData v2) const
+    {
+        return v2.contains(v1, charmap);
+    }
+
+    template <class A, class B>
+    bool operator()(A, B) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    bool operator()(int64_t, int64_t, bool, bool) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+
+    static std::string description()
+    {
+        return "CONTAINS";
+    }
+
+    static const int condition = -1;
+};
+
+// Does v2 contain something like v1 (wildcard matching)?
+struct Like : public HackClass {
+    bool operator()(StringData v1, const char*, const char*, StringData v2, bool = false, bool = false) const
+    {
+        return v2.like(v1);
+    }
+    bool operator()(StringData v1, StringData v2, bool = false, bool = false) const
+    {
+        return v2.like(v1);
+    }
+    bool operator()(BinaryData, BinaryData, bool = false, bool = false) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+
+    template <class A, class B>
+    bool operator()(A, B) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+
+    bool operator()(int64_t, int64_t, bool, bool) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+
+    static std::string description()
+    {
+        return "LIKE";
+    }
+
+    static const int condition = -1;
+};
+
+// Does v2 begin with v1?
+struct BeginsWith : public HackClass {
+    bool operator()(StringData v1, const char*, const char*, StringData v2, bool = false, bool = false) const
+    {
+        return v2.begins_with(v1);
+    }
+    bool operator()(StringData v1, StringData v2, bool = false, bool = false) const
+    {
+        return v2.begins_with(v1);
+    }
+    bool operator()(BinaryData v1, BinaryData v2, bool = false, bool = false) const
+    {
+        return v2.begins_with(v1);
+    }
+
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    template <class A, class B>
+    bool operator()(A, B) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+
+    static std::string description()
+    {
+        return "BEGINSWITH";
+    }
+
+    static const int condition = -1;
+};
+
+// Does v2 end with v1?
+struct EndsWith : public HackClass {
+    bool operator()(StringData v1, const char*, const char*, StringData v2, bool = false, bool = false) const
+    {
+        return v2.ends_with(v1);
+    }
+    bool operator()(StringData v1, StringData v2, bool = false, bool = false) const
+    {
+        return v2.ends_with(v1);
+    }
+    bool operator()(BinaryData v1, BinaryData v2, bool = false, bool = false) const
+    {
+        return v2.ends_with(v1);
+    }
+
+    template <class A, class B>
+    bool operator()(A, B) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+
+    static std::string description()
+    {
+        return "ENDSWITH";
+    }
+
+    static const int condition = -1;
+};
+
+struct Equal {
+    static const int avx = 0x00; // _CMP_EQ_OQ
+    //    bool operator()(const bool v1, const bool v2, bool v1null = false, bool v2null = false) const { return v1 ==
+    //    v2; }
+    bool operator()(StringData v1, const char*, const char*, StringData v2, bool = false, bool = false) const
+    {
+        return v1 == v2;
+    }
+    bool operator()(BinaryData v1, BinaryData v2, bool = false, bool = false) const
+    {
+        return v1 == v2;
+    }
+
+    template <class T>
+    bool operator()(const T& v1, const T& v2, bool v1null = false, bool v2null = false) const
+    {
+        return (v1null && v2null) || (!v1null && !v2null && v1 == v2);
+    }
+    static const int condition = cond_Equal;
+    bool can_match(int64_t v, int64_t lbound, int64_t ubound)
+    {
+        return (v >= lbound && v <= ubound);
+    }
+    bool will_match(int64_t v, int64_t lbound, int64_t ubound)
+    {
+        return (v == 0 && ubound == 0 && lbound == 0);
+    }
+
+    static std::string description()
+    {
+        return "==";
+    }
+};
+
+struct NotEqual {
+    static const int avx = 0x0B; // _CMP_FALSE_OQ
+    bool operator()(StringData v1, const char*, const char*, StringData v2, bool = false, bool = false) const
+    {
+        return v1 != v2;
+    }
+    // bool operator()(BinaryData v1, BinaryData v2, bool = false, bool = false) const { return v1 != v2; }
+
+    template <class T>
+    bool operator()(const T& v1, const T& v2, bool v1null = false, bool v2null = false) const
+    {
+        if (!v1null && !v2null)
+            return v1 != v2;
+
+        if (v1null && v2null)
+            return false;
+
+        return true;
+    }
+
+    static const int condition = cond_NotEqual;
+    bool can_match(int64_t v, int64_t lbound, int64_t ubound)
+    {
+        return !(v == 0 && ubound == 0 && lbound == 0);
+    }
+    bool will_match(int64_t v, int64_t lbound, int64_t ubound)
+    {
+        return (v > ubound || v < lbound);
+    }
+
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+
+    static std::string description()
+    {
+        return "!=";
+    }
+};
+
+// Does v2 contain v1?
+struct ContainsIns : public HackClass {
+    bool operator()(StringData v1, const char* v1_upper, const char* v1_lower, StringData v2, bool = false,
+                    bool = false) const
+    {
+        if (v2.is_null() && !v1.is_null())
+            return false;
+
+        if (v1.size() == 0 && !v2.is_null())
+            return true;
+
+        return search_case_fold(v2, v1_upper, v1_lower, v1.size()) != v2.size();
+    }
+
+    // Slow version, used if caller hasn't stored an upper and lower case version
+    bool operator()(StringData v1, StringData v2, bool = false, bool = false) const
+    {
+        if (v2.is_null() && !v1.is_null())
+            return false;
+
+        if (v1.size() == 0 && !v2.is_null())
+            return true;
+
+        std::string v1_upper = case_map(v1, true, IgnoreErrors);
+        std::string v1_lower = case_map(v1, false, IgnoreErrors);
+        return search_case_fold(v2, v1_upper.c_str(), v1_lower.c_str(), v1.size()) != v2.size();
+    }
+    
+    // Case insensitive Boyer-Moore version
+    bool operator()(StringData v1, const char* v1_upper, const char* v1_lower, const std::array<uint8_t, 256> &charmap, StringData v2) const
+    {
+        if (v2.is_null() && !v1.is_null())
+            return false;
+        
+        if (v1.size() == 0 && !v2.is_null())
+            return true;
+        
+        return contains_ins(v2, v1_upper, v1_lower, v1.size(), charmap);
+    }
+
+
+    template <class A, class B>
+    bool operator()(A, B) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    bool operator()(int64_t, int64_t, bool, bool) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+
+    static std::string description()
+    {
+        return "CONTAINS[c]";
+    }
+
+    static const int condition = -1;
+};
+
+// Does v2 contain something like v1 (wildcard matching)?
+struct LikeIns : public HackClass {
+    bool operator()(StringData v1, const char* v1_upper, const char* v1_lower, StringData v2, bool = false,
+                    bool = false) const
+    {
+        if (v2.is_null() || v1.is_null()) {
+            return (v2.is_null() && v1.is_null());
+        }
+
+        return string_like_ins(v2, v1_lower, v1_upper);
+    }
+
+    // Slow version, used if caller hasn't stored an upper and lower case version
+    bool operator()(StringData v1, StringData v2, bool = false, bool = false) const
+    {
+        if (v2.is_null() || v1.is_null()) {
+            return (v2.is_null() && v1.is_null());
+        }
+
+        std::string v1_upper = case_map(v1, true, IgnoreErrors);
+        std::string v1_lower = case_map(v1, false, IgnoreErrors);
+        return string_like_ins(v2, v1_lower, v1_upper);
+    }
+
+    template <class A, class B>
+    bool operator()(A, B) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    bool operator()(int64_t, int64_t, bool, bool) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+
+    static std::string description()
+    {
+        return "LIKE[c]";
+    }
+
+    static const int condition = -1;
+};
+
+// Does v2 begin with v1?
+struct BeginsWithIns : public HackClass {
+    bool operator()(StringData v1, const char* v1_upper, const char* v1_lower, StringData v2, bool = false,
+                    bool = false) const
+    {
+        if (v2.is_null() && !v1.is_null())
+            return false;
+        return v1.size() <= v2.size() && equal_case_fold(v2.prefix(v1.size()), v1_upper, v1_lower);
+    }
+
+    // Slow version, used if caller hasn't stored an upper and lower case version
+    bool operator()(StringData v1, StringData v2, bool = false, bool = false) const
+    {
+        if (v2.is_null() && !v1.is_null())
+            return false;
+
+        if (v1.size() > v2.size())
+            return false;
+        std::string v1_upper = case_map(v1, true, IgnoreErrors);
+        std::string v1_lower = case_map(v1, false, IgnoreErrors);
+        return equal_case_fold(v2.prefix(v1.size()), v1_upper.c_str(), v1_lower.c_str());
+    }
+
+    template <class A, class B>
+    bool operator()(A, B) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    bool operator()(int64_t, int64_t, bool, bool) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+
+    static std::string description()
+    {
+        return "BEGINSWITH[c]";
+    }
+
+    static const int condition = -1;
+};
+
+// Does v2 end with v1?
+struct EndsWithIns : public HackClass {
+    bool operator()(StringData v1, const char* v1_upper, const char* v1_lower, StringData v2, bool = false,
+                    bool = false) const
+    {
+        if (v2.is_null() && !v1.is_null())
+            return false;
+
+        return v1.size() <= v2.size() && equal_case_fold(v2.suffix(v1.size()), v1_upper, v1_lower);
+    }
+
+    // Slow version, used if caller hasn't stored an upper and lower case version
+    bool operator()(StringData v1, StringData v2, bool = false, bool = false) const
+    {
+        if (v2.is_null() && !v1.is_null())
+            return false;
+
+        if (v1.size() > v2.size())
+            return false;
+        std::string v1_upper = case_map(v1, true, IgnoreErrors);
+        std::string v1_lower = case_map(v1, false, IgnoreErrors);
+        return equal_case_fold(v2.suffix(v1.size()), v1_upper.c_str(), v1_lower.c_str());
+    }
+
+    template <class A, class B>
+    bool operator()(A, B) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    bool operator()(int64_t, int64_t, bool, bool) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+
+    static std::string description()
+    {
+        return "ENDSWITH[c]";
+    }
+
+    static const int condition = -1;
+};
+
+struct EqualIns : public HackClass {
+    bool operator()(StringData v1, const char* v1_upper, const char* v1_lower, StringData v2, bool = false,
+                    bool = false) const
+    {
+        if (v1.is_null() != v2.is_null())
+            return false;
+
+        return v1.size() == v2.size() && equal_case_fold(v2, v1_upper, v1_lower);
+    }
+
+    // Slow version, used if caller hasn't stored an upper and lower case version
+    bool operator()(StringData v1, StringData v2, bool = false, bool = false) const
+    {
+        if (v1.is_null() != v2.is_null())
+            return false;
+
+        if (v1.size() != v2.size())
+            return false;
+        std::string v1_upper = case_map(v1, true, IgnoreErrors);
+        std::string v1_lower = case_map(v1, false, IgnoreErrors);
+        return equal_case_fold(v2, v1_upper.c_str(), v1_lower.c_str());
+    }
+
+    template <class A, class B>
+    bool operator()(A, B) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    bool operator()(int64_t, int64_t, bool, bool) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+
+    static std::string description()
+    {
+        return "==[c]";
+    }
+
+    static const int condition = -1;
+};
+
+struct NotEqualIns : public HackClass {
+    bool operator()(StringData v1, const char* v1_upper, const char* v1_lower, StringData v2, bool = false,
+                    bool = false) const
+    {
+        if (v1.is_null() != v2.is_null())
+            return true;
+        return v1.size() != v2.size() || !equal_case_fold(v2, v1_upper, v1_lower);
+    }
+
+    // Slow version, used if caller hasn't stored an upper and lower case version
+    bool operator()(StringData v1, StringData v2, bool = false, bool = false) const
+    {
+        if (v1.is_null() != v2.is_null())
+            return true;
+
+        if (v1.size() != v2.size())
+            return true;
+        std::string v1_upper = case_map(v1, true, IgnoreErrors);
+        std::string v1_lower = case_map(v1, false, IgnoreErrors);
+        return !equal_case_fold(v2, v1_upper.c_str(), v1_lower.c_str());
+    }
+
+    template <class A, class B>
+    bool operator()(A, B) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+
+    static std::string description()
+    {
+        return "!=[c]";
+    }
+
+    static const int condition = -1;
+};
+
+struct Greater {
+    static const int avx = 0x1E; // _CMP_GT_OQ
+    template <class T>
+    bool operator()(const T& v1, const T& v2, bool v1null = false, bool v2null = false) const
+    {
+        if (v1null || v2null)
+            return false;
+
+        return v1 > v2;
+    }
+    static const int condition = cond_Greater;
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+
+    bool can_match(int64_t v, int64_t lbound, int64_t ubound)
+    {
+        static_cast<void>(lbound);
+        return ubound > v;
+    }
+    bool will_match(int64_t v, int64_t lbound, int64_t ubound)
+    {
+        static_cast<void>(ubound);
+        return lbound > v;
+    }
+
+    static std::string description()
+    {
+        return ">";
+    }
+};
+
+struct None {
+    template <class T>
+    bool operator()(const T&, const T&, bool = false, bool = false) const
+    {
+        return true;
+    }
+    static const int condition = cond_None;
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    bool can_match(int64_t v, int64_t lbound, int64_t ubound)
+    {
+        static_cast<void>(lbound);
+        static_cast<void>(ubound);
+        static_cast<void>(v);
+        return true;
+    }
+    bool will_match(int64_t v, int64_t lbound, int64_t ubound)
+    {
+        static_cast<void>(lbound);
+        static_cast<void>(ubound);
+        static_cast<void>(v);
+        return true;
+    }
+
+    static std::string description()
+    {
+        return "none";
+    }
+};
+
+struct NotNull {
+    template <class T>
+    bool operator()(const T&, const T&, bool v = false, bool = false) const
+    {
+        return !v;
+    }
+    static const int condition = cond_LeftNotNull;
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    bool can_match(int64_t v, int64_t lbound, int64_t ubound)
+    {
+        static_cast<void>(lbound);
+        static_cast<void>(ubound);
+        static_cast<void>(v);
+        return true;
+    }
+    bool will_match(int64_t v, int64_t lbound, int64_t ubound)
+    {
+        static_cast<void>(lbound);
+        static_cast<void>(ubound);
+        static_cast<void>(v);
+        return true;
+    }
+    static std::string description()
+    {
+        return "!= NULL";
+    }
+};
+
+
+struct Less {
+    static const int avx = 0x11; // _CMP_LT_OQ
+    template <class T>
+    bool operator()(const T& v1, const T& v2, bool v1null = false, bool v2null = false) const
+    {
+        if (v1null || v2null)
+            return false;
+
+        return v1 < v2;
+    }
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    static const int condition = cond_Less;
+    bool can_match(int64_t v, int64_t lbound, int64_t ubound)
+    {
+        static_cast<void>(ubound);
+        return lbound < v;
+    }
+    bool will_match(int64_t v, int64_t lbound, int64_t ubound)
+    {
+        static_cast<void>(lbound);
+        return ubound < v;
+    }
+    static std::string description()
+    {
+        return "<";
+    }
+};
+
+struct LessEqual : public HackClass {
+    static const int avx = 0x12; // _CMP_LE_OQ
+    template <class T>
+    bool operator()(const T& v1, const T& v2, bool v1null = false, bool v2null = false) const
+    {
+        if (v1null && v2null)
+            return true;
+
+        return (!v1null && !v2null && v1 <= v2);
+    }
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    static std::string description()
+    {
+        return "<=";
+    }
+    static const int condition = -1;
+};
+
+struct GreaterEqual : public HackClass {
+    static const int avx = 0x1D; // _CMP_GE_OQ
+    template <class T>
+    bool operator()(const T& v1, const T& v2, bool v1null = false, bool v2null = false) const
+    {
+        if (v1null && v2null)
+            return true;
+
+        return (!v1null && !v2null && v1 >= v2);
+    }
+    template <class A, class B, class C, class D>
+    bool operator()(A, B, C, D) const
+    {
+        REALM_ASSERT(false);
+        return false;
+    }
+    static std::string description()
+    {
+        return ">=";
+    }
+    static const int condition = -1;
+};
+
+
+// CompareLess is a temporary hack to have a generalized way to compare any realm types. Todo, enable correct <
+// operator of StringData (currently gives circular header dependency with utf8.hpp)
+template <class T>
+struct CompareLess {
+    static bool compare(T v1, T v2, bool = false, bool = false)
+    {
+        return v1 < v2;
+    }
+};
+template <>
+struct CompareLess<StringData> {
+    static bool compare(StringData v1, StringData v2, bool = false, bool = false)
+    {
+        bool ret = utf8_compare(v1.data(), v2.data());
+        return ret;
+    }
+};
+
+} // namespace realm
+
+#endif // REALM_QUERY_CONDITIONS_HPP