make folly::Range literal type
authorPhilip Pronin <philipp@fb.com>
Thu, 17 Jul 2014 20:05:02 +0000 (13:05 -0700)
committerTudor Bosman <tudorb@fb.com>
Mon, 21 Jul 2014 19:22:03 +0000 (12:22 -0700)
Summary:
7.1.5 [dcl.constexpr] / 9 (N3337) requires type to be literal to use it
in `constexpr` object declaration (seems to be not enforced by GCC 4.8?)

Currently `folly::Range<>` fails one of the requirements:

* is an aggregate type, or has at least one constexpr constructor or
constructor template that is not a copy or move constructor,

Test Plan: fbconfig folly/test:range_test && fbmake runtests_opt -j32

Reviewed By: lucian@fb.com

Subscribers: chaoyc, search-fbcode-diffs@, unicorn-diffs@

FB internal diff: D1441646

Tasks: 4720575

folly/Range.h
folly/test/RangeTest.cpp

index f556986544a54ccbee21d5bb30a5535626333df3..4d7b1bcb9d673450bb450fae85df3308d9f8e8d4 100644 (file)
@@ -163,21 +163,21 @@ public:
   static const size_type npos;
 
   // Works for all iterators
-  Range() : b_(), e_() {
+  constexpr Range() : b_(), e_() {
   }
 
 public:
   // Works for all iterators
-  Range(Iter start, Iter end) : b_(start), e_(end) {
+  constexpr Range(Iter start, Iter end) : b_(start), e_(end) {
   }
 
   // Works only for random-access iterators
-  Range(Iter start, size_t size)
+  constexpr Range(Iter start, size_t size)
       : b_(start), e_(start + size) { }
 
 #if FOLLY_HAVE_CONSTEXPR_STRLEN
   // Works only for Range<const char*>
-  /* implicit */ constexpr Range(Iter str)
+  constexpr /* implicit */ Range(Iter str)
       : b_(str), e_(str + strlen(str)) {}
 #else
   // Works only for Range<const char*>
@@ -291,7 +291,7 @@ public:
   template <class OtherIter, typename std::enable_if<
      (!std::is_same<Iter, OtherIter>::value &&
       std::is_convertible<OtherIter, Iter>::value), int>::type = 0>
-  /* implicit */ Range(const Range<OtherIter>& other)
+  constexpr /* implicit */ Range(const Range<OtherIter>& other)
     : b_(other.begin()),
       e_(other.end()) {
   }
@@ -302,7 +302,7 @@ public:
     (!std::is_same<Iter, OtherIter>::value &&
      !std::is_convertible<OtherIter, Iter>::value &&
      std::is_constructible<Iter, const OtherIter&>::value), int>::type = 0>
-  explicit Range(const Range<OtherIter>& other)
+  constexpr explicit Range(const Range<OtherIter>& other)
     : b_(other.begin()),
       e_(other.end()) {
   }
index 0bf328aba3be863a165081c5333650ac4d660cf3..78e881a19062e0bed1ff97a11800f930e9504d7d 100644 (file)
 
 #include <folly/Range.h>
 
+#include <sys/mman.h>
 #include <array>
-#include <boost/range/concepts.hpp>
 #include <cstdlib>
-#include <gtest/gtest.h>
 #include <iterator>
 #include <limits>
 #include <random>
 #include <string>
-#include <sys/mman.h>
+#include <type_traits>
 #include <vector>
+#include <boost/range/concepts.hpp>
+#include <gtest/gtest.h>
 
 namespace folly { namespace detail {
 
@@ -44,6 +45,8 @@ size_t qfind_first_byte_of_byteset(const StringPiece& haystack,
 using namespace folly;
 using namespace std;
 
+static_assert(std::is_literal_type<StringPiece>::value, "");
+
 BOOST_CONCEPT_ASSERT((boost::RandomAccessRangeConcept<StringPiece>));
 
 TEST(StringPiece, All) {