X-Git-Url: https://git.mdrn.pl/wl-app.git/blobdiff_plain/53b27422d140022594fc241cca91c3183be57bca..48b2fe9f7c2dc3d9aeaaa6dbfb27c7da4f3235ff:/iOS/Pods/Realm/include/execution_context_id.hpp?ds=inline diff --git a/iOS/Pods/Realm/include/execution_context_id.hpp b/iOS/Pods/Realm/include/execution_context_id.hpp new file mode 100644 index 0000000..9c0ae62 --- /dev/null +++ b/iOS/Pods/Realm/include/execution_context_id.hpp @@ -0,0 +1,123 @@ +//////////////////////////////////////////////////////////////////////////// +// +// 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 utilied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#ifndef REALM_OS_EXECUTION_CONTEXT_ID_HPP +#define REALM_OS_EXECUTION_CONTEXT_ID_HPP + +#if defined(__GNUC__) && __GNUC__ < 5 +// GCC 4.9 doesn't have std::alligned_union so polyfill +#include "util/aligned_union.hpp" +#else +#include +#endif + +#include +#include + +#include +#include + +namespace realm { + +// An identifier for an execution context other than a thread. +// Different execution contexts must have different IDs. +using AbstractExecutionContextID = uintptr_t; + +// Identifies an execution context in which a Realm will be used. +// Can contain either a std::thread::id or an AbstractExecutionContextID. +// +// FIXME: This can eventually be: +// using AnyExecutionContextID = std::variant; +class AnyExecutionContextID { + enum class Type { + Thread, + Abstract, + }; + +public: + + // Convert from the representation used by Realm::Config, where the absence of an + // explicit abstract execution context indicates that the current thread's identifier + // should be used. + AnyExecutionContextID(util::Optional maybe_abstract_id) + { + if (maybe_abstract_id) + *this = AnyExecutionContextID(*maybe_abstract_id); + else + *this = AnyExecutionContextID(std::this_thread::get_id()); + } + + AnyExecutionContextID(std::thread::id thread_id) : AnyExecutionContextID(Type::Thread, std::move(thread_id)) { } + AnyExecutionContextID(AbstractExecutionContextID abstract_id) : AnyExecutionContextID(Type::Abstract, abstract_id) { } + + template + bool contains() const + { + return TypeForStorageType::value == m_type; + } + + template + StorageType get() const + { + REALM_ASSERT_DEBUG(contains()); + return *reinterpret_cast(&m_storage); + } + + bool operator==(const AnyExecutionContextID& other) const + { + return m_type == other.m_type && std::memcmp(&m_storage, &other.m_storage, sizeof(m_storage)) == 0; + } + + bool operator!=(const AnyExecutionContextID& other) const + { + return !(*this == other); + } + +private: + template + AnyExecutionContextID(Type type, T value) : m_type(type) + { + // operator== relies on being able to compare the raw bytes of m_storage, + // so zero everything before intializing the portion in use. + std::memset(&m_storage, 0, sizeof(m_storage)); + new (&m_storage) T(std::move(value)); + } + + template struct TypeForStorageType; + +#if defined(__GNUC__) && __GNUC__ < 5 + util::AlignedUnion<1, std::thread::id, AbstractExecutionContextID>::type m_storage; +#else + std::aligned_union<1, std::thread::id, AbstractExecutionContextID>::type m_storage; +#endif + Type m_type; +}; + +template <> +struct AnyExecutionContextID::TypeForStorageType { + constexpr static Type value = Type::Thread; +}; + +template <> +struct AnyExecutionContextID::TypeForStorageType { + constexpr static Type value = Type::Abstract; +}; + +} // namespace realm + +#endif // REALM_OS_EXECUTION_CONTEXT_ID_HPP