Mercurial > hg > sv-dependency-builds
diff osx/include/kj/one-of.h @ 147:45360b968bf4
Cap'n Proto v0.6 + build for OSX
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Mon, 22 May 2017 10:01:37 +0100 |
parents | 41e769c91eca |
children |
line wrap: on
line diff
--- a/osx/include/kj/one-of.h Mon Mar 06 13:29:58 2017 +0000 +++ b/osx/include/kj/one-of.h Mon May 22 10:01:37 2017 +0100 @@ -1,150 +1,155 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#ifndef KJ_ONE_OF_H_ -#define KJ_ONE_OF_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "common.h" - -namespace kj { - -namespace _ { // private - -template <uint i, typename Key, typename First, typename... Rest> -struct TypeIndex_ { static constexpr uint value = TypeIndex_<i + 1, Key, Rest...>::value; }; -template <uint i, typename Key, typename... Rest> -struct TypeIndex_<i, Key, Key, Rest...> { static constexpr uint value = i; }; - -} // namespace _ (private) - -template <typename... Variants> -class OneOf { - template <typename Key> - static inline constexpr uint typeIndex() { return _::TypeIndex_<1, Key, Variants...>::value; } - // Get the 1-based index of Key within the type list Types. - -public: - inline OneOf(): tag(0) {} - OneOf(const OneOf& other) { copyFrom(other); } - OneOf(OneOf&& other) { moveFrom(other); } - ~OneOf() { destroy(); } - - OneOf& operator=(const OneOf& other) { if (tag != 0) destroy(); copyFrom(other); return *this; } - OneOf& operator=(OneOf&& other) { if (tag != 0) destroy(); moveFrom(other); return *this; } - - inline bool operator==(decltype(nullptr)) const { return tag == 0; } - inline bool operator!=(decltype(nullptr)) const { return tag != 0; } - - template <typename T> - bool is() const { - return tag == typeIndex<T>(); - } - - template <typename T> - T& get() { - KJ_IREQUIRE(is<T>(), "Must check OneOf::is<T>() before calling get<T>()."); - return *reinterpret_cast<T*>(space); - } - template <typename T> - const T& get() const { - KJ_IREQUIRE(is<T>(), "Must check OneOf::is<T>() before calling get<T>()."); - return *reinterpret_cast<const T*>(space); - } - - template <typename T, typename... Params> - void init(Params&&... params) { - if (tag != 0) destroy(); - ctor(*reinterpret_cast<T*>(space), kj::fwd<Params>(params)...); - tag = typeIndex<T>(); - } - -private: - uint tag; - - static inline constexpr size_t maxSize(size_t a) { - return a; - } - template <typename... Rest> - static inline constexpr size_t maxSize(size_t a, size_t b, Rest... rest) { - return maxSize(kj::max(a, b), rest...); - } - // Returns the maximum of all the parameters. - // TODO(someday): Generalize the above template and make it common. I tried, but C++ decided to - // be difficult so I cut my losses. - - union { - byte space[maxSize(sizeof(Variants)...)]; - - void* forceAligned; - // TODO(someday): Use C++11 alignas() once we require GCC 4.8 / Clang 3.3. - }; - - template <typename... T> - inline void doAll(T... t) {} - - template <typename T> - inline bool destroyVariant() { - if (tag == typeIndex<T>()) { - tag = 0; - dtor(*reinterpret_cast<T*>(space)); - } - return false; - } - void destroy() { - doAll(destroyVariant<Variants>()...); - } - - template <typename T> - inline bool copyVariantFrom(const OneOf& other) { - if (other.is<T>()) { - ctor(*reinterpret_cast<T*>(space), other.get<T>()); - } - return false; - } - void copyFrom(const OneOf& other) { - // Initialize as a copy of `other`. Expects that `this` starts out uninitialized, so the tag - // is invalid. - tag = other.tag; - doAll(copyVariantFrom<Variants>(other)...); - } - - template <typename T> - inline bool moveVariantFrom(OneOf& other) { - if (other.is<T>()) { - ctor(*reinterpret_cast<T*>(space), kj::mv(other.get<T>())); - } - return false; - } - void moveFrom(OneOf& other) { - // Initialize as a copy of `other`. Expects that `this` starts out uninitialized, so the tag - // is invalid. - tag = other.tag; - doAll(moveVariantFrom<Variants>(other)...); - } -}; - -} // namespace kj - -#endif // KJ_ONE_OF_H_ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_ONE_OF_H_ +#define KJ_ONE_OF_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "common.h" + +namespace kj { + +namespace _ { // private + +template <uint i, typename Key, typename First, typename... Rest> +struct TypeIndex_ { static constexpr uint value = TypeIndex_<i + 1, Key, Rest...>::value; }; +template <uint i, typename Key, typename... Rest> +struct TypeIndex_<i, Key, Key, Rest...> { static constexpr uint value = i; }; + +} // namespace _ (private) + +template <typename... Variants> +class OneOf { + template <typename Key> + static inline constexpr uint typeIndex() { return _::TypeIndex_<1, Key, Variants...>::value; } + // Get the 1-based index of Key within the type list Types. + +public: + inline OneOf(): tag(0) {} + OneOf(const OneOf& other) { copyFrom(other); } + OneOf(OneOf&& other) { moveFrom(other); } + ~OneOf() { destroy(); } + + OneOf& operator=(const OneOf& other) { if (tag != 0) destroy(); copyFrom(other); return *this; } + OneOf& operator=(OneOf&& other) { if (tag != 0) destroy(); moveFrom(other); return *this; } + + inline bool operator==(decltype(nullptr)) const { return tag == 0; } + inline bool operator!=(decltype(nullptr)) const { return tag != 0; } + + template <typename T> + bool is() const { + return tag == typeIndex<T>(); + } + + template <typename T> + T& get() { + KJ_IREQUIRE(is<T>(), "Must check OneOf::is<T>() before calling get<T>()."); + return *reinterpret_cast<T*>(space); + } + template <typename T> + const T& get() const { + KJ_IREQUIRE(is<T>(), "Must check OneOf::is<T>() before calling get<T>()."); + return *reinterpret_cast<const T*>(space); + } + + template <typename T, typename... Params> + T& init(Params&&... params) { + if (tag != 0) destroy(); + ctor(*reinterpret_cast<T*>(space), kj::fwd<Params>(params)...); + tag = typeIndex<T>(); + return *reinterpret_cast<T*>(space); + } + +private: + uint tag; + + static inline constexpr size_t maxSize(size_t a) { + return a; + } + template <typename... Rest> + static inline constexpr size_t maxSize(size_t a, size_t b, Rest... rest) { + return maxSize(kj::max(a, b), rest...); + } + // Returns the maximum of all the parameters. + // TODO(someday): Generalize the above template and make it common. I tried, but C++ decided to + // be difficult so I cut my losses. + + static constexpr auto spaceSize = maxSize(sizeof(Variants)...); + // TODO(msvc): This constant could just as well go directly inside space's bracket's, where it's + // used, but MSVC suffers a parse error on `...`. + + union { + byte space[spaceSize]; + + void* forceAligned; + // TODO(someday): Use C++11 alignas() once we require GCC 4.8 / Clang 3.3. + }; + + template <typename... T> + inline void doAll(T... t) {} + + template <typename T> + inline bool destroyVariant() { + if (tag == typeIndex<T>()) { + tag = 0; + dtor(*reinterpret_cast<T*>(space)); + } + return false; + } + void destroy() { + doAll(destroyVariant<Variants>()...); + } + + template <typename T> + inline bool copyVariantFrom(const OneOf& other) { + if (other.is<T>()) { + ctor(*reinterpret_cast<T*>(space), other.get<T>()); + } + return false; + } + void copyFrom(const OneOf& other) { + // Initialize as a copy of `other`. Expects that `this` starts out uninitialized, so the tag + // is invalid. + tag = other.tag; + doAll(copyVariantFrom<Variants>(other)...); + } + + template <typename T> + inline bool moveVariantFrom(OneOf& other) { + if (other.is<T>()) { + ctor(*reinterpret_cast<T*>(space), kj::mv(other.get<T>())); + } + return false; + } + void moveFrom(OneOf& other) { + // Initialize as a copy of `other`. Expects that `this` starts out uninitialized, so the tag + // is invalid. + tag = other.tag; + doAll(moveVariantFrom<Variants>(other)...); + } +}; + +} // namespace kj + +#endif // KJ_ONE_OF_H_