// Copyright 2021 The Android Open Source Project // // 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. // 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. #pragma once #include #include namespace gfxstream::guest { namespace fit { namespace internal { // Utility to return the first type in a parameter pack. template struct First; template struct First { using Type = FirstType; }; template using First_t = typename First::Type; // Utility to count the occurences of type T in the parameter pack Ts. template struct OccurencesOf : std::integral_constant {}; template struct OccurencesOf : std::integral_constant::value> {}; template struct OccurencesOf : std::integral_constant::value + OccurencesOf::value> {}; template constexpr size_t occurencesOf = OccurencesOf::value; // Utility to remove const, volatile, and reference qualifiers. template using RemoveCvref_t = std::remove_cv_t>; // Evaluates to truth-like when type T matches type U with cv-reference removed. template using NotSameType = std::negation>>; // Concept helper for constructors. template using RequiresConditions = std::enable_if_t, bool>; // Concept helper for assignment operators. template using AssignmentRequiresConditions = std::enable_if_t, std::add_lvalue_reference_t>; // Evaluates to true when every element type of Ts is trivially destructible. template constexpr bool isTriviallyDestructible = std::conjunction_v...>; // Evaluates to true when every element type of Ts is trivially copyable. template constexpr bool isTriviallyCopyable = (std::conjunction_v...> && std::conjunction_v...>); // Evaluates to true when every element type of Ts is trivially movable. template constexpr bool isTriviallyMovable = (std::conjunction_v...> && std::conjunction_v...>); // Enable if relational operator is convertible to bool and the optional // conditions are true. template using enable_relop_t = std::enable_if_t<(std::is_convertible::value && std::conjunction_v), bool>; template struct Identity { using Type = T; }; // Evaluates to true when T is an unbounded array. template struct IsUnboundedArray : std::conjunction, std::negation>> {}; // Returns true when T is a complete type or an unbounded array. template constexpr bool isCompleteOrUnboundedArray(Identity) { return true; } template constexpr bool isCompleteOrUnboundedArray(Identity) { return std::disjunction, std::is_function, std::is_void, IsUnboundedArray>::value; } // Using swap for ADL. This directive is contained within the fit::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 struct IsSwappable : std::false_type { static_assert(isCompleteOrUnboundedArray(Identity{}), "T must be a complete type or an unbounded array!"); }; template struct IsSwappable(), std::declval()))>> : std::true_type { static_assert(isCompleteOrUnboundedArray(Identity{}), "T must be a complete type or an unbounded array!"); }; // Evaluates to true when T is nothrow swappable. template struct IsNothrowSwappable : std::false_type { static_assert(isCompleteOrUnboundedArray(Identity{}), "T must be a complete type or an unbounded array!"); }; template struct IsNothrowSwappable(), std::declval()))>> : std::integral_constant(), std::declval()))> { static_assert(isCompleteOrUnboundedArray(Identity{}), "T must be a complete type or an unbounded array!"); }; } // namespace internal } // namespace fit } // namespace gfxstream::guest