// Copyright 2017 The Abseil Authors. // // 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. // // absl/utility:utility is an extension of the header // // It provides stand-ins for C++14's std::integer_sequence and // related utilities. They are intended to be exactly equivalent. // - integer_sequence == std::integer_sequence // - index_sequence == std::index_sequence // - make_integer_sequence == std::make_integer_sequence // - make_index_sequence == std::make_index_sequence // - index_sequence_for == std::index_sequence_for // // It also provides the tag types in_place_t, in_place_type_t, and // in_place_index_t, as well as the constant in_place, and constexpr std::move // and std::forward impolementations in C++11. // // References: // http://en.cppreference.com/w/cpp/utility/integer_sequence // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html // // Example: // // Unpack a tuple for use as a function call's argument list. // // template // auto Impl(F f, const Tup& tup, index_sequence) // -> decltype(f(std::get(tup) ...)) { // return f(std::get(tup) ...); // } // // template // using TupIdxSeq = make_index_sequence::value>; // // template // auto ApplyFromTuple(F f, const Tup& tup) // -> decltype(Impl(f, tup, TupIdxSeq{})) { // return Impl(f, tup, TupIdxSeq{}); // } #ifndef ABSL_UTILITY_UTILITY_H_ #define ABSL_UTILITY_UTILITY_H_ #include #include #include #include "absl/base/config.h" #include "absl/meta/type_traits.h" namespace absl { // Equivalent to std::integer_sequence. // // Function templates can deduce compile-time integer sequences by accepting // an argument of integer_sequence. This is a common need when // working with C++11 variadic templates. // // T - the integer type of the sequence elements // ...Ints - a parameter pack of T values representing the sequence template struct integer_sequence { using value_type = T; static constexpr size_t size() noexcept { return sizeof...(Ints); } }; // Equivalent to std::index_sequence. // // Alias for an integer_sequence of size_t. template using index_sequence = integer_sequence; namespace utility_internal { template struct Extend; // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. template struct Extend, SeqSize, 0> { using type = integer_sequence; }; template struct Extend, SeqSize, 1> { using type = integer_sequence; }; // Recursion helper for 'make_integer_sequence'. // 'Gen::type' is an alias for 'integer_sequence'. template struct Gen { using type = typename Extend::type, N / 2, N % 2>::type; }; template struct Gen { using type = integer_sequence; }; } // namespace utility_internal // Compile-time sequences of integers // Equivalent to std::make_integer_sequence. // // make_integer_sequence is integer_sequence; template using make_integer_sequence = typename utility_internal::Gen::type; // Equivalent to std::make_index_sequence. // // make_index_sequence is index_sequence<0, 1, ..., N-1>; template using make_index_sequence = make_integer_sequence; // Equivalent to std::index_sequence_for. // // Convert a typename pack into an index sequence of the same length. template using index_sequence_for = make_index_sequence; // Tag types #ifdef ABSL_HAVE_STD_OPTIONAL using std::in_place_t; using std::in_place; #else // ABSL_HAVE_STD_OPTIONAL // Tag type used in order to specify in-place construction, such as with // absl::optional. struct in_place_t {}; extern const in_place_t in_place; #endif // ABSL_HAVE_STD_OPTIONAL #ifdef ABSL_HAVE_STD_ANY using std::in_place_type_t; #else // Tag types used for in-place construction when the type to construct needs to // be specified, such as with absl::variant and absl::any. template struct in_place_type_t {}; #endif // ABSL_HAVE_STD_ANY template struct in_place_index_t {}; // Constexpr move and forward template constexpr absl::remove_reference_t&& move(T&& t) noexcept { return static_cast&&>(t); } template constexpr T&& forward( absl::remove_reference_t& t) noexcept { // NOLINT(runtime/references) return static_cast(t); } } // namespace absl #endif // ABSL_UTILITY_UTILITY_H_