// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. // This source code is licensed under both the GPLv2 (found in the // COPYING file in the root directory) and Apache 2.0 License // (found in the LICENSE.Apache file in the root directory). #pragma once #include #include namespace folly { /** * Backports from C++17 of: * std::in_place_t * std::in_place_type_t * std::in_place_index_t * std::in_place * std::in_place_type * std::in_place_index */ struct in_place_tag {}; template struct in_place_type_tag {}; template struct in_place_index_tag {}; using in_place_t = in_place_tag (&)(in_place_tag); template using in_place_type_t = in_place_type_tag (&)(in_place_type_tag); template using in_place_index_t = in_place_index_tag (&)(in_place_index_tag); inline in_place_tag in_place(in_place_tag = {}) { return {}; } template inline in_place_type_tag in_place_type(in_place_type_tag = {}) { return {}; } template inline in_place_index_tag in_place_index(in_place_index_tag = {}) { return {}; } template T exchange(T& obj, U&& new_value) { T old_value = std::move(obj); obj = std::forward(new_value); return old_value; } namespace utility_detail { template struct make_seq_cat; template < template class S, typename T, T... Ta, T... Tb, T... Tc> struct make_seq_cat, S, S> { using type = S; }; // Not parameterizing by `template class, typename` because // clang precisely v4.0 fails to compile that. Note that clang v3.9 and v5.0 // handle that code correctly. // // For this to work, `S0` is required to be `Sequence` and `S1` is required // to be `Sequence`. template struct make_seq { template using apply = typename make_seq_cat< typename make_seq::template apply, typename make_seq::template apply, typename make_seq::template apply>::type; }; template <> struct make_seq<1> { template using apply = S1; }; template <> struct make_seq<0> { template using apply = S0; }; } // namespace utility_detail // TODO: Remove after upgrading to C++14 baseline template struct integer_sequence { using value_type = T; static constexpr std::size_t size() noexcept { return sizeof...(Ints); } }; template using index_sequence = integer_sequence; template using make_integer_sequence = typename utility_detail::make_seq< Size>::template apply, integer_sequence>; template using make_index_sequence = make_integer_sequence; template using index_sequence_for = make_index_sequence; /** * A simple helper for getting a constant reference to an object. * * Example: * * std::vector v{1,2,3}; * // The following two lines are equivalent: * auto a = const_cast&>(v).begin(); * auto b = folly::as_const(v).begin(); * * Like C++17's std::as_const. See http://wg21.link/p0007 */ template T const& as_const(T& t) noexcept { return t; } template void as_const(T const&&) = delete; } // namespace folly