#ifndef ABSL_UTILITY_UTILITY_H_
#define ABSL_UTILITY_UTILITY_H_
#include <cstddef>
#include <cstdlib>
#include <tuple>
#include <utility>
#include "absl/base/config.h"
#include "absl/base/internal/inline_variable.h"
#include "absl/base/internal/invoke.h"
#include "absl/meta/type_traits.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
using std::exchange;
using std::forward;
using std::index_sequence;
using std::index_sequence_for;
using std::integer_sequence;
using std::make_index_sequence;
using std::make_integer_sequence;
using std::move;
namespace utility_internal {
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;
};
}
#ifdef ABSL_USES_STD_OPTIONAL
using std::in_place_t;
using std::in_place;
#else
struct in_place_t {};
ABSL_INTERNAL_INLINE_CONSTEXPR(in_place_t, in_place, {});
#endif
#if defined(ABSL_USES_STD_ANY) || defined(ABSL_USES_STD_VARIANT)
using std::in_place_type;
using std::in_place_type_t;
#else
template <typename T>
using in_place_type_t = void (*)(utility_internal::InPlaceTypeTag<T>);
template <typename T>
void in_place_type(utility_internal::InPlaceTypeTag<T>) {}
#endif
#ifdef ABSL_USES_STD_VARIANT
using std::in_place_index;
using std::in_place_index_t;
#else
template <size_t I>
using in_place_index_t = void (*)(utility_internal::InPlaceIndexTag<I>);
template <size_t I>
void in_place_index(utility_internal::InPlaceIndexTag<I>) {}
#endif
namespace utility_internal {
template <typename Functor, typename Tuple, std::size_t... Indexes>
auto apply_helper(Functor&& functor, Tuple&& t, index_sequence<Indexes...>)
-> decltype(absl::base_internal::invoke(
absl::forward<Functor>(functor),
std::get<Indexes>(absl::forward<Tuple>(t))...)) {
return absl::base_internal::invoke(
absl::forward<Functor>(functor),
std::get<Indexes>(absl::forward<Tuple>(t))...);
}
}
template <typename Functor, typename Tuple>
auto apply(Functor&& functor, Tuple&& t)
-> decltype(utility_internal::apply_helper(
absl::forward<Functor>(functor), absl::forward<Tuple>(t),
absl::make_index_sequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>{})) {
return utility_internal::apply_helper(
absl::forward<Functor>(functor), absl::forward<Tuple>(t),
absl::make_index_sequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>{});
}
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))...);
}
}
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>{});
}
ABSL_NAMESPACE_END
}
#endif