Fix some implicit truncations in the interaction with OpenSSL APIs
[folly.git] / folly / Range.h
index 97a7f1d082ba213f6c2025a855199bb171bdd00d..b715e1d04fe74f9e784168a896976aa7ae89b3f5 100644 (file)
@@ -363,16 +363,30 @@ public:
     // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71448
     return e_ - b_;
   }
-  size_type walk_size() const {
+  constexpr size_type walk_size() const {
     return std::distance(b_, e_);
   }
-  bool empty() const { return b_ == e_; }
-  Iter data() const { return b_; }
-  Iter start() const { return b_; }
-  Iter begin() const { return b_; }
-  Iter end() const { return e_; }
-  Iter cbegin() const { return b_; }
-  Iter cend() const { return e_; }
+  constexpr bool empty() const {
+    return b_ == e_;
+  }
+  constexpr Iter data() const {
+    return b_;
+  }
+  constexpr Iter start() const {
+    return b_;
+  }
+  constexpr Iter begin() const {
+    return b_;
+  }
+  constexpr Iter end() const {
+    return e_;
+  }
+  constexpr Iter cbegin() const {
+    return b_;
+  }
+  constexpr Iter cend() const {
+    return e_;
+  }
   value_type& front() {
     assert(b_ < e_);
     return *b_;
@@ -864,7 +878,7 @@ void swap(Range<T>& lhs, Range<T>& rhs) {
  * Create a range from two iterators, with type deduction.
  */
 template <class Iter>
-Range<Iter> range(Iter first, Iter last) {
+constexpr Range<Iter> range(Iter first, Iter last) {
   return Range<Iter>(first, last);
 }
 
@@ -872,18 +886,25 @@ Range<Iter> range(Iter first, Iter last) {
  * Creates a range to reference the contents of a contiguous-storage container.
  */
 // Use pointers for types with '.data()' member
-template <class Collection,
-          class T = typename std::remove_pointer<
-              decltype(std::declval<Collection>().data())>::type>
-Range<T*> range(Collection&& v) {
+template <
+    class Collection,
+    class T = typename std::remove_pointer<
+        decltype(std::declval<Collection>().data())>::type>
+constexpr Range<T*> range(Collection&& v) {
   return Range<T*>(v.data(), v.data() + v.size());
 }
 
 template <class T, size_t n>
-Range<T*> range(T (&array)[n]) {
+constexpr Range<T*> range(T (&array)[n]) {
   return Range<T*>(array, 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);
+}
+
 typedef Range<const char*> StringPiece;
 typedef Range<char*> MutableStringPiece;
 typedef Range<const unsigned char*> ByteRange;