From c2e754829628d1e9b7a16b3389cfdace76950fdf Mon Sep 17 00:00:00 2001 From: misterg Date: Tue, 19 Sep 2017 16:54:40 -0400 Subject: Initial Commit --- absl/utility/utility.h | 177 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 absl/utility/utility.h (limited to 'absl/utility/utility.h') diff --git a/absl/utility/utility.h b/absl/utility/utility.h new file mode 100644 index 00000000..4f4a0624 --- /dev/null +++ b/absl/utility/utility.h @@ -0,0 +1,177 @@ +// 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_ -- cgit v1.2.3