Fix a pair of non-ascii quotes that made their way into AsyncSocket
[folly.git] / folly / Traits.h
index 45f005cb4443bb17ca8f968e907b6d342eca5720..c50948ccff8a9438dfe586e8173050469ad4da7a 100644 (file)
@@ -90,16 +90,15 @@ namespace folly {
 
 namespace traits_detail {
 
-#define FOLLY_HAS_TRUE_XXX(name)                          \
-  BOOST_MPL_HAS_XXX_TRAIT_DEF(name);                      \
-  template <class T> struct name ## _is_true              \
-    : std::is_same<typename T::name, std::true_type> {};  \
-  template <class T> struct has_true_ ## name             \
-    : std::conditional<                                   \
-        has_ ## name <T>::value,                          \
-        name ## _is_true<T>,                              \
-        std::false_type                                   \
-      >:: type {};
+#define FOLLY_HAS_TRUE_XXX(name)                                             \
+  BOOST_MPL_HAS_XXX_TRAIT_DEF(name)                                          \
+  template <class T>                                                         \
+  struct name##_is_true : std::is_same<typename T::name, std::true_type> {}; \
+  template <class T>                                                         \
+  struct has_true_##name : std::conditional<                                 \
+                               has_##name<T>::value,                         \
+                               name##_is_true<T>,                            \
+                               std::false_type>::type {};
 
 FOLLY_HAS_TRUE_XXX(IsRelocatable)
 FOLLY_HAS_TRUE_XXX(IsZeroInitializable)
@@ -337,10 +336,13 @@ struct is_negative_impl<T, false> {
 
 // folly::to integral specializations can end up generating code
 // inside what are really static ifs (not executed because of the templated
-// types) that violate -Wsign-compare so suppress them in order to not prevent
-// all calling code from using it.
+// types) that violate -Wsign-compare and/or -Wbool-compare so suppress them
+// in order to not prevent all calling code from using it.
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wsign-compare"
+#if __GNUC_PREREQ(5, 0)
+#pragma GCC diagnostic ignored "-Wbool-compare"
+#endif
 
 template <typename RHS, RHS rhs, typename LHS>
 bool less_than_impl(LHS const lhs) {
@@ -350,8 +352,6 @@ bool less_than_impl(LHS const lhs) {
     lhs < rhs;
 }
 
-#pragma GCC diagnostic pop
-
 template <typename RHS, RHS rhs, typename LHS>
 bool greater_than_impl(LHS const lhs) {
   return
@@ -360,6 +360,8 @@ bool greater_than_impl(LHS const lhs) {
     lhs > rhs;
 }
 
+#pragma GCC diagnostic pop
+
 } // namespace detail {
 
 // same as `x < 0`
@@ -403,21 +405,66 @@ bool greater_than(LHS const lhs) {
 struct construct_in_place_t {};
 constexpr construct_in_place_t construct_in_place{};
 
+/**
+ * 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<int>);
+ *
+ *    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<int>);
+ *
+ *    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
 
 // gcc-5.0 changed string's implementation in libgcc to be non-relocatable
 #if __GNUC__ < 5
-FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3(std::basic_string);
+FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3(std::basic_string)
 #endif
-FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::vector);
-FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::list);
-FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::deque);
-FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::unique_ptr);
-FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(std::shared_ptr);
-FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(std::function);
+FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::vector)
+FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::list)
+FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::deque)
+FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::unique_ptr)
+FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(std::shared_ptr)
+FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(std::function)
 
 // Boost
-FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(boost::shared_ptr);
+FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(boost::shared_ptr)
 
 #define FOLLY_CREATE_HAS_MEMBER_TYPE_TRAITS(classname, type_name) \
   template <typename T> \