aboutsummaryrefslogtreecommitdiff
path: root/third_party/fuchsia/repo/sdk/lib/stdcompat/include/lib/stdcompat/internal/utility.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/fuchsia/repo/sdk/lib/stdcompat/include/lib/stdcompat/internal/utility.h')
-rw-r--r--third_party/fuchsia/repo/sdk/lib/stdcompat/include/lib/stdcompat/internal/utility.h137
1 files changed, 137 insertions, 0 deletions
diff --git a/third_party/fuchsia/repo/sdk/lib/stdcompat/include/lib/stdcompat/internal/utility.h b/third_party/fuchsia/repo/sdk/lib/stdcompat/include/lib/stdcompat/internal/utility.h
new file mode 100644
index 000000000..a5da381ae
--- /dev/null
+++ b/third_party/fuchsia/repo/sdk/lib/stdcompat/include/lib/stdcompat/internal/utility.h
@@ -0,0 +1,137 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LIB_STDCOMPAT_INCLUDE_LIB_STDCOMPAT_INTERNAL_UTILITY_H_
+#define LIB_STDCOMPAT_INCLUDE_LIB_STDCOMPAT_INTERNAL_UTILITY_H_
+
+#include <cstddef>
+#include <utility>
+
+#include "../type_traits.h"
+
+namespace cpp17 {
+namespace internal {
+
+template <typename Tag>
+struct instantiate_templated_tag {
+ static constexpr const Tag storage{};
+};
+
+template <typename Tag>
+constexpr const Tag instantiate_templated_tag<Tag>::storage;
+
+template <typename T, typename ValueType, ValueType Value>
+struct inline_storage {
+ static constexpr const ValueType storage{Value};
+};
+
+template <typename T, typename ValueType, ValueType Value>
+constexpr const ValueType inline_storage<T, ValueType, Value>::storage;
+
+// Utility to return the first type in a parameter pack.
+template <typename... Ts>
+struct first;
+template <typename First, typename... Rest>
+struct first<First, Rest...> {
+ using type = First;
+};
+
+template <typename... Ts>
+using first_t = typename first<Ts...>::type;
+
+// Utility to count the occurences of type T in the parameter pack Ts.
+template <typename T, typename... Ts>
+struct occurences_of : std::integral_constant<std::size_t, 0> {};
+template <typename T, typename U>
+struct occurences_of<T, U> : std::integral_constant<std::size_t, std::is_same<T, U>::value> {};
+template <typename T, typename First, typename... Rest>
+struct occurences_of<T, First, Rest...>
+ : std::integral_constant<std::size_t,
+ occurences_of<T, First>::value + occurences_of<T, Rest...>::value> {};
+
+template <typename T, typename... Ts>
+constexpr std::size_t occurences_of_v = occurences_of<T, Ts...>::value;
+
+// Evaluates to truth-like when type T matches type U with cv-reference removed.
+template <typename T, typename U>
+using not_same_type = negation<std::is_same<T, ::cpp20::remove_cvref_t<U>>>;
+
+// Concept helper for constructors.
+template <typename... Conditions>
+using requires_conditions = std::enable_if_t<conjunction_v<Conditions...>, bool>;
+
+// Concept helper for assignment operators.
+template <typename Return, typename... Conditions>
+using assignment_requires_conditions =
+ std::enable_if_t<conjunction_v<Conditions...>, std::add_lvalue_reference_t<Return>>;
+
+// Evaluates to true when every element type of Ts is trivially destructible.
+template <typename... Ts>
+constexpr bool is_trivially_destructible_v = conjunction_v<std::is_trivially_destructible<Ts>...>;
+
+// Evaluates to true when every element type of Ts is trivially copyable.
+template <typename... Ts>
+constexpr bool is_trivially_copyable_v =
+ (conjunction_v<std::is_trivially_copy_assignable<Ts>...> &&
+ conjunction_v<std::is_trivially_copy_constructible<Ts>...>);
+
+// Evaluates to true when every element type of Ts is trivially movable.
+template <typename... Ts>
+constexpr bool is_trivially_movable_v =
+ (conjunction_v<std::is_trivially_move_assignable<Ts>...> &&
+ conjunction_v<std::is_trivially_move_constructible<Ts>...>);
+
+// Enable if relational operator is convertible to bool and the optional
+// conditions are true.
+template <typename Op, typename... Conditions>
+using enable_relop_t =
+ std::enable_if_t<(std::is_convertible<Op, bool>::value && conjunction_v<Conditions...>), bool>;
+
+// Returns true when T is a complete type or an unbounded array.
+template <typename T, std::size_t = sizeof(T)>
+constexpr bool is_complete_or_unbounded_array(::cpp20::type_identity<T>) {
+ return true;
+}
+template <typename Identity, typename T = typename Identity::type>
+constexpr bool is_complete_or_unbounded_array(Identity) {
+ return disjunction<std::is_reference<T>, std::is_function<T>, std::is_void<T>,
+ ::cpp20::is_unbounded_array<T>>::value;
+}
+
+// Using swap for ADL. This directive is contained within the cpp17::internal
+// namespace, which prevents leaking std::swap into user namespaces. Doing this
+// at namespace scope is necessary to lookup swap via ADL while preserving the
+// noexcept() specification of the resulting lookup.
+using std::swap;
+
+// Evaluates to true when T is swappable.
+template <typename T, typename = void>
+struct is_swappable : std::false_type {
+ static_assert(is_complete_or_unbounded_array(::cpp20::type_identity<T>{}),
+ "T must be a complete type or an unbounded array!");
+};
+template <typename T>
+struct is_swappable<T, void_t<decltype(swap(std::declval<T&>(), std::declval<T&>()))>>
+ : std::true_type {
+ static_assert(is_complete_or_unbounded_array(::cpp20::type_identity<T>{}),
+ "T must be a complete type or an unbounded array!");
+};
+
+// Evaluates to true when T is nothrow swappable.
+template <typename T, typename = void>
+struct is_nothrow_swappable : std::false_type {
+ static_assert(is_complete_or_unbounded_array(::cpp20::type_identity<T>{}),
+ "T must be a complete type or an unbounded array!");
+};
+template <typename T>
+struct is_nothrow_swappable<T, void_t<decltype(swap(std::declval<T&>(), std::declval<T&>()))>>
+ : std::integral_constant<bool, noexcept(swap(std::declval<T&>(), std::declval<T&>()))> {
+ static_assert(is_complete_or_unbounded_array(::cpp20::type_identity<T>{}),
+ "T must be a complete type or an unbounded array!");
+};
+
+} // namespace internal
+} // namespace cpp17
+
+#endif // LIB_STDCOMPAT_INCLUDE_LIB_STDCOMPAT_INTERNAL_UTILITY_H_