diff options
Diffstat (limited to 'third_party/immer/immer/detail/combine_standard_layout.hpp')
-rw-r--r-- | third_party/immer/immer/detail/combine_standard_layout.hpp | 235 |
1 files changed, 0 insertions, 235 deletions
diff --git a/third_party/immer/immer/detail/combine_standard_layout.hpp b/third_party/immer/immer/detail/combine_standard_layout.hpp deleted file mode 100644 index 55c69bc91682..000000000000 --- a/third_party/immer/immer/detail/combine_standard_layout.hpp +++ /dev/null @@ -1,235 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <type_traits> - -#if defined(__GNUC__) && __GNUC__ == 7 && __GNUC_MINOR__ == 1 -#define IMMER_BROKEN_STANDARD_LAYOUT_DETECTION 1 -#define immer_offsetof(st, m) ((std::size_t) & (((st*) 0)->m)) -#else -#define IMMER_BROKEN_STANDARD_LAYOUT_DETECTION 0 -#define immer_offsetof offsetof -#endif - -namespace immer { -namespace detail { - -// -// Metafunction that returns a standard layout struct that combines -// all the standard layout types in `Ts...`, while making sure that -// empty base optimizations are used. -// -// To query a part of the type do `get<my_part>(x)`; -// -// This is useful when putting together a type that merges various -// types coming from different policies. Some of them might be empty, -// so we shall enable empty base optimizations. But if we just -// inherit from all of them, we would break the "standard layout" -// rules, preventing us from using `offseof(...)`. So metafunction -// will generate the type by sometimes inheriting, sometimes adding as -// member. -// -// Note that the types are added to the combined type from right to -// left! -// -template <typename... Ts> -struct combine_standard_layout; - -template <typename... Ts> -using combine_standard_layout_t = typename combine_standard_layout<Ts...>::type; - -namespace csl { - -template <typename T> -struct type_t -{}; - -template <typename U, typename T> -U& get(T& x); - -template <typename U, typename T> -const U& get(const T& x); - -template <typename T, typename Next = void> -struct inherit -{ - struct type - : T - , Next - { - using Next::get_; - - template <typename U> - friend decltype(auto) get(type& x) - { - return x.get_(type_t<U>{}); - } - template <typename U> - friend decltype(auto) get(const type& x) - { - return x.get_(type_t<U>{}); - } - - T& get_(type_t<T>) { return *this; } - const T& get_(type_t<T>) const { return *this; } - }; -}; - -template <typename T> -struct inherit<T, void> -{ - struct type : T - { - template <typename U> - friend decltype(auto) get(type& x) - { - return x.get_(type_t<U>{}); - } - template <typename U> - friend decltype(auto) get(const type& x) - { - return x.get_(type_t<U>{}); - } - - T& get_(type_t<T>) { return *this; } - const T& get_(type_t<T>) const { return *this; } - }; -}; - -template <typename T, typename Next = void> -struct member -{ - struct type : Next - { - T d; - - using Next::get_; - - template <typename U> - friend decltype(auto) get(type& x) - { - return x.get_(type_t<U>{}); - } - template <typename U> - friend decltype(auto) get(const type& x) - { - return x.get_(type_t<U>{}); - } - - T& get_(type_t<T>) { return d; } - const T& get_(type_t<T>) const { return d; } - }; -}; - -template <typename T> -struct member<T, void> -{ - struct type - { - T d; - - template <typename U> - friend decltype(auto) get(type& x) - { - return x.get_(type_t<U>{}); - } - template <typename U> - friend decltype(auto) get(const type& x) - { - return x.get_(type_t<U>{}); - } - - T& get_(type_t<T>) { return d; } - const T& get_(type_t<T>) const { return d; } - }; -}; - -template <typename T, typename Next> -struct member_two -{ - struct type - { - Next n; - T d; - - template <typename U> - friend decltype(auto) get(type& x) - { - return x.get_(type_t<U>{}); - } - template <typename U> - friend decltype(auto) get(const type& x) - { - return x.get_(type_t<U>{}); - } - - T& get_(type_t<T>) { return d; } - const T& get_(type_t<T>) const { return d; } - - template <typename U> - auto get_(type_t<U> t) -> decltype(auto) - { - return n.get_(t); - } - template <typename U> - auto get_(type_t<U> t) const -> decltype(auto) - { - return n.get_(t); - } - }; -}; - -template <typename... Ts> -struct combine_standard_layout_aux; - -template <typename T> -struct combine_standard_layout_aux<T> -{ - static_assert(std::is_standard_layout<T>::value, ""); - - using type = typename std::conditional_t<std::is_empty<T>::value, - csl::inherit<T>, - csl::member<T>>::type; -}; - -template <typename T, typename... Ts> -struct combine_standard_layout_aux<T, Ts...> -{ - static_assert(std::is_standard_layout<T>::value, ""); - - using this_t = T; - using next_t = typename combine_standard_layout_aux<Ts...>::type; - - static constexpr auto empty_this = std::is_empty<this_t>::value; - static constexpr auto empty_next = std::is_empty<next_t>::value; - - using type = typename std::conditional_t< - empty_this, - inherit<this_t, next_t>, - std::conditional_t<empty_next, - member<this_t, next_t>, - member_two<this_t, next_t>>>::type; -}; - -} // namespace csl - -using csl::get; - -template <typename... Ts> -struct combine_standard_layout -{ - using type = typename csl::combine_standard_layout_aux<Ts...>::type; -#if !IMMER_BROKEN_STANDARD_LAYOUT_DETECTION - static_assert(std::is_standard_layout<type>::value, ""); -#endif -}; - -} // namespace detail -} // namespace immer |