summaryrefslogtreecommitdiff
path: root/absl/utility/utility.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/utility/utility.h')
-rw-r--r--absl/utility/utility.h99
1 files changed, 78 insertions, 21 deletions
diff --git a/absl/utility/utility.h b/absl/utility/utility.h
index 66e22dc2..bc9af048 100644
--- a/absl/utility/utility.h
+++ b/absl/utility/utility.h
@@ -4,7 +4,7 @@
// 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
+// https://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,
@@ -25,6 +25,7 @@
// * index_sequence_for<Ts...> == std::index_sequence_for<Ts...>
// * apply<Functor, Tuple> == std::apply<Functor, Tuple>
// * exchange<T> == std::exchange<T>
+// * make_from_tuple<T> == std::make_from_tuple<T>
//
// This header file 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
@@ -32,10 +33,9 @@
//
// References:
//
-// http://en.cppreference.com/w/cpp/utility/integer_sequence
-// http://en.cppreference.com/w/cpp/utility/apply
+// https://en.cppreference.com/w/cpp/utility/integer_sequence
+// https://en.cppreference.com/w/cpp/utility/apply
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html
-//
#ifndef ABSL_UTILITY_UTILITY_H_
#define ABSL_UTILITY_UTILITY_H_
@@ -51,7 +51,7 @@
#include "absl/meta/type_traits.h"
namespace absl {
-inline namespace lts_2018_12_18 {
+inline namespace lts_2019_08_08 {
// integer_sequence
//
@@ -115,6 +115,20 @@ struct Gen<T, 0> {
using type = integer_sequence<T>;
};
+template <typename T>
+struct InPlaceTypeTag {
+ explicit InPlaceTypeTag() = delete;
+ InPlaceTypeTag(const InPlaceTypeTag&) = delete;
+ InPlaceTypeTag& operator=(const InPlaceTypeTag&) = delete;
+};
+
+template <size_t I>
+struct InPlaceIndexTag {
+ explicit InPlaceIndexTag() = delete;
+ InPlaceIndexTag(const InPlaceIndexTag&) = delete;
+ InPlaceIndexTag& operator=(const InPlaceIndexTag&) = delete;
+};
+
} // namespace utility_internal
// Compile-time sequences of integers
@@ -164,6 +178,7 @@ ABSL_INTERNAL_INLINE_CONSTEXPR(in_place_t, in_place, {});
#endif // ABSL_HAVE_STD_OPTIONAL
#if defined(ABSL_HAVE_STD_ANY) || defined(ABSL_HAVE_STD_VARIANT)
+using std::in_place_type;
using std::in_place_type_t;
#else
@@ -173,10 +188,14 @@ using std::in_place_type_t;
// be specified, such as with `absl::any`, designed to be a drop-in replacement
// for C++17's `std::in_place_type_t`.
template <typename T>
-struct in_place_type_t {};
+using in_place_type_t = void (*)(utility_internal::InPlaceTypeTag<T>);
+
+template <typename T>
+void in_place_type(utility_internal::InPlaceTypeTag<T>) {}
#endif // ABSL_HAVE_STD_ANY || ABSL_HAVE_STD_VARIANT
#ifdef ABSL_HAVE_STD_VARIANT
+using std::in_place_index;
using std::in_place_index_t;
#else
@@ -186,7 +205,10 @@ using std::in_place_index_t;
// be specified, such as with `absl::any`, designed to be a drop-in replacement
// for C++17's `std::in_place_index_t`.
template <size_t I>
-struct in_place_index_t {};
+using in_place_index_t = void (*)(utility_internal::InPlaceIndexTag<I>);
+
+template <size_t I>
+void in_place_index(utility_internal::InPlaceIndexTag<I>) {}
#endif // ABSL_HAVE_STD_VARIANT
// Constexpr move and forward
@@ -235,25 +257,33 @@ auto apply_helper(Functor&& functor, Tuple&& t, index_sequence<Indexes...>)
//
// Example:
//
-// class Foo{void Bar(int);};
-// void user_function(int, string);
-// void user_function(std::unique_ptr<Foo>);
+// class Foo {
+// public:
+// void Bar(int);
+// };
+// void user_function1(int, std::string);
+// void user_function2(std::unique_ptr<Foo>);
+// auto user_lambda = [](int, int) {};
//
// int main()
// {
-// std::tuple<int, string> tuple1(42, "bar");
-// // Invokes the user function overload on int, string.
-// absl::apply(&user_function, tuple1);
+// std::tuple<int, std::string> tuple1(42, "bar");
+// // Invokes the first user function on int, std::string.
+// absl::apply(&user_function1, tuple1);
//
-// auto foo = absl::make_unique<Foo>();
-// std::tuple<Foo*, int> tuple2(foo.get(), 42);
-// // Invokes the method Bar on foo with one argument 42.
-// absl::apply(&Foo::Bar, foo.get(), 42);
-//
-// std::tuple<std::unique_ptr<Foo>> tuple3(absl::make_unique<Foo>());
+// std::tuple<std::unique_ptr<Foo>> tuple2(absl::make_unique<Foo>());
// // Invokes the user function that takes ownership of the unique
// // pointer.
-// absl::apply(&user_function, std::move(tuple));
+// absl::apply(&user_function2, std::move(tuple2));
+//
+// auto foo = absl::make_unique<Foo>();
+// std::tuple<Foo*, int> tuple3(foo.get(), 42);
+// // Invokes the method Bar on foo with one argument, 42.
+// absl::apply(&Foo::Bar, tuple3);
+//
+// std::tuple<int, int> tuple4(8, 9);
+// // Invokes a lambda.
+// absl::apply(user_lambda, tuple4);
// }
template <typename Functor, typename Tuple>
auto apply(Functor&& functor, Tuple&& t)
@@ -287,7 +317,34 @@ T exchange(T& obj, U&& new_value) {
return old_value;
}
-} // inline namespace lts_2018_12_18
+namespace utility_internal {
+template <typename T, typename Tuple, size_t... I>
+T make_from_tuple_impl(Tuple&& tup, absl::index_sequence<I...>) {
+ return T(std::get<I>(std::forward<Tuple>(tup))...);
+}
+} // namespace utility_internal
+
+// make_from_tuple
+//
+// Given the template parameter type `T` and a tuple of arguments
+// `std::tuple(arg0, arg1, ..., argN)` constructs an object of type `T` as if by
+// calling `T(arg0, arg1, ..., argN)`.
+//
+// Example:
+//
+// std::tuple<const char*, size_t> args("hello world", 5);
+// auto s = absl::make_from_tuple<std::string>(args);
+// assert(s == "hello");
+//
+template <typename T, typename Tuple>
+constexpr T make_from_tuple(Tuple&& tup) {
+ return utility_internal::make_from_tuple_impl<T>(
+ std::forward<Tuple>(tup),
+ absl::make_index_sequence<
+ std::tuple_size<absl::decay_t<Tuple>>::value>{});
+}
+
+} // inline namespace lts_2019_08_08
} // namespace absl
#endif // ABSL_UTILITY_UTILITY_H_