#include <folly/portability/Constexpr.h>
#include <folly/portability/String.h>
-#include <algorithm>
#include <boost/operators.hpp>
+#include <glog/logging.h>
+#include <algorithm>
+#include <array>
#include <climits>
#include <cstddef>
#include <cstring>
-#include <glog/logging.h>
#include <iosfwd>
#include <stdexcept>
#include <string>
e_(other.end()) {
}
+ /**
+ * Allow explicit construction of Range() from a std::array of a
+ * convertible type.
+ *
+ * For instance, this allows constructing StringPiece from a
+ * std::array<char, N> or a std::array<const char, N>
+ */
+ template <
+ class T,
+ size_t N,
+ typename = typename std::enable_if<
+ std::is_convertible<const T*, Iter>::value>::type>
+ constexpr explicit Range(const std::array<T, N>& array)
+ : b_{array.empty() ? nullptr : &array.at(0)},
+ e_{array.empty() ? nullptr : &array.at(0) + N} {}
+ template <
+ class T,
+ size_t N,
+ typename =
+ typename std::enable_if<std::is_convertible<T*, Iter>::value>::type>
+ constexpr explicit Range(std::array<T, N>& array)
+ : b_{array.empty() ? nullptr : &array.at(0)},
+ e_{array.empty() ? nullptr : &array.at(0) + N} {}
+
Range& operator=(const Range& rhs) & = default;
Range& operator=(Range&& rhs) & = default;
template <class T, size_t n>
constexpr Range<const T*> range(const std::array<T, n>& array) {
- using r = Range<const T*>;
- return array.empty() ? r{} : r(&array.at(0), &array.at(0) + n);
+ return Range<const T*>{array};
}
typedef Range<const char*> StringPiece;
EXPECT_EQ(subpiece1.end(), subpiece2.end());
}
+TEST(Range, ArrayConstructors) {
+ auto charArray = std::array<char, 4>{{'t', 'e', 's', 't'}};
+ auto constCharArray = std::array<char, 6>{{'f', 'o', 'o', 'b', 'a', 'r'}};
+ auto emptyArray = std::array<char, 0>{};
+
+ auto sp1 = StringPiece{charArray};
+ EXPECT_EQ(4, sp1.size());
+ EXPECT_EQ(charArray.data(), sp1.data());
+
+ auto sp2 = StringPiece(constCharArray);
+ EXPECT_EQ(6, sp2.size());
+ EXPECT_EQ(constCharArray.data(), sp2.data());
+
+ auto msp = MutableStringPiece(charArray);
+ EXPECT_EQ(4, msp.size());
+ EXPECT_EQ(charArray.data(), msp.data());
+
+ auto esp = StringPiece(emptyArray);
+ EXPECT_EQ(0, esp.size());
+ EXPECT_EQ(nullptr, esp.data());
+
+ auto emsp = MutableStringPiece(emptyArray);
+ EXPECT_EQ(0, emsp.size());
+ EXPECT_EQ(nullptr, emsp.data());
+
+ static constexpr std::array<int, 4> numArray = {{3, 17, 1, 9}};
+ constexpr auto numRange = Range<const int*>{numArray};
+ EXPECT_EQ(17, numRange[1]);
+
+ static constexpr std::array<int, 0> emptyNumArray{};
+ constexpr auto emptyNumRange = Range<const int*>{emptyNumArray};
+ EXPECT_EQ(0, emptyNumRange.size());
+}
+
TEST(Range, ConstexprAccessors) {
constexpr StringPiece piece = range("hello");
static_assert(piece.size() == 6u, "");