add Range constructors from std::array
[folly.git] / folly / Range.h
index d205a7b3d654c8b839f6346ae740899ad997ac16..bfbb4eb0f609c0547da193f3f0875a36f36219cd 100644 (file)
 #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>
@@ -332,6 +333,30 @@ public:
       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;
 
@@ -907,8 +932,7 @@ constexpr Range<T*> range(T (&array)[n]) {
 
 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;