From: Yedidya Feldblum Date: Sun, 2 Jul 2017 17:22:31 +0000 (-0700) Subject: Move in_place and friends to Utility.h X-Git-Tag: v2017.07.03.00~3 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8f8a5e472c5de694bde9cbfe508a782027591fcf;p=folly.git Move in_place and friends to Utility.h Summary: [Folly] Move `in_place` and friends to `Utility.h`. Document that they are backports from C++17. Reviewed By: Orvid Differential Revision: D5362364 fbshipit-source-id: 495cb7f339fc558f20d89100c141fc7a243239d5 --- diff --git a/folly/ExceptionWrapper.h b/folly/ExceptionWrapper.h index 8016168e..d8b6a4d8 100644 --- a/folly/ExceptionWrapper.h +++ b/folly/ExceptionWrapper.h @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef __GNUC__ #pragma GCC diagnostic push diff --git a/folly/Expected.h b/folly/Expected.h index 22f43943..a12a6fc4 100644 --- a/folly/Expected.h +++ b/folly/Expected.h @@ -32,8 +32,9 @@ #include #include #include -#include // for in_place_t +#include #include +#include #define FOLLY_EXPECTED_ID(X) FB_CONCATENATE(FB_CONCATENATE(Folly, X), __LINE__) diff --git a/folly/Traits.h b/folly/Traits.h index cda84d24..cc30fad2 100644 --- a/folly/Traits.h +++ b/folly/Traits.h @@ -606,92 +606,6 @@ bool greater_than(LHS const lhs) { RHS, rhs, typename std::remove_reference::type >(lhs); } - -namespace traits_detail { -struct InPlaceTag {}; -template -struct InPlaceTypeTag {}; -template -struct InPlaceIndexTag {}; -} - -/** - * Like std::piecewise_construct, a tag type & instance used for in-place - * construction of non-movable contained types, e.g. by Synchronized. - * Follows the naming and design of std::in_place suggested in - * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0032r2.pdf - */ -using in_place_t = traits_detail::InPlaceTag (&)(traits_detail::InPlaceTag); - -template -using in_place_type_t = - traits_detail::InPlaceTypeTag (&)(traits_detail::InPlaceTypeTag); - -template -using in_place_index_t = - traits_detail::InPlaceIndexTag (&)(traits_detail::InPlaceIndexTag); - -inline traits_detail::InPlaceTag in_place(traits_detail::InPlaceTag = {}) { - return {}; -} - -template -inline traits_detail::InPlaceTypeTag in_place_type( - traits_detail::InPlaceTypeTag = {}) { - return {}; -} - -template -inline traits_detail::InPlaceIndexTag in_place_index( - traits_detail::InPlaceIndexTag = {}) { - return {}; -} - -/** - * Initializer lists are a powerful compile time syntax introduced in C++11 - * but due to their often conflicting syntax they are not used by APIs for - * construction. - * - * Further standard conforming compilers *strongly* favor an - * std::initalizer_list overload for construction if one exists. The - * following is a simple tag used to disambiguate construction with - * initializer lists and regular uniform initialization. - * - * For example consider the following case - * - * class Something { - * public: - * explicit Something(int); - * Something(std::intiializer_list); - * - * operator int(); - * }; - * - * ... - * Something something{1}; // SURPRISE!! - * - * The last call to instantiate the Something object will go to the - * initializer_list overload. Which may be surprising to users. - * - * If however this tag was used to disambiguate such construction it would be - * easy for users to see which construction overload their code was referring - * to. For example - * - * class Something { - * public: - * explicit Something(int); - * Something(folly::initlist_construct_t, std::initializer_list); - * - * operator int(); - * }; - * - * ... - * Something something_one{1}; // not the initializer_list overload - * Something something_two{folly::initlist_construct, {1}}; // correct - */ -struct initlist_construct_t {}; -constexpr initlist_construct_t initlist_construct{}; - } // namespace folly // Assume nothing when compiling with MSVC. diff --git a/folly/Utility.h b/folly/Utility.h index 1d378618..d84abb7b 100644 --- a/folly/Utility.h +++ b/folly/Utility.h @@ -132,6 +132,85 @@ using make_index_sequence = detail::make_index_sequence; #endif +/** + * 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 {}; +} + +/** + * Initializer lists are a powerful compile time syntax introduced in C++11 + * but due to their often conflicting syntax they are not used by APIs for + * construction. + * + * Further standard conforming compilers *strongly* favor an + * std::initalizer_list overload for construction if one exists. The + * following is a simple tag used to disambiguate construction with + * initializer lists and regular uniform initialization. + * + * For example consider the following case + * + * class Something { + * public: + * explicit Something(int); + * Something(std::intiializer_list); + * + * operator int(); + * }; + * + * ... + * Something something{1}; // SURPRISE!! + * + * The last call to instantiate the Something object will go to the + * initializer_list overload. Which may be surprising to users. + * + * If however this tag was used to disambiguate such construction it would be + * easy for users to see which construction overload their code was referring + * to. For example + * + * class Something { + * public: + * explicit Something(int); + * Something(folly::initlist_construct_t, std::initializer_list); + * + * operator int(); + * }; + * + * ... + * Something something_one{1}; // not the initializer_list overload + * Something something_two{folly::initlist_construct, {1}}; // correct + */ +struct initlist_construct_t {}; +constexpr initlist_construct_t initlist_construct{}; + /** * A simple function object that passes its argument through unchanged. *