Add needsPeerVerification function to check if peer cert should be verified
[folly.git] / folly / small_vector.h
index b03eec05f3a3281ba3b73b05dba18d86300dab2b..db36acc072b5c9ddd0de5cf83a235a683435447c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  *
  * @author Jordan DeLong <delong.j@fb.com>
  */
-#ifndef FOLLY_SMALL_VECTOR_H_
-#define FOLLY_SMALL_VECTOR_H_
 
-#include <folly/Portability.h>
+#pragma once
 
 #include <stdexcept>
 #include <cstdlib>
 #include <boost/mpl/empty.hpp>
 #include <boost/mpl/size.hpp>
 #include <boost/mpl/count.hpp>
-#include <boost/mpl/max.hpp>
 
+#include <folly/FormatTraits.h>
 #include <folly/Malloc.h>
-
-#if defined(__GNUC__) && FOLLY_X64
-# include <folly/SmallLocks.h>
-# define FB_PACK_ATTR FOLLY_PACK_ATTR
-# define FB_PACK_PUSH FOLLY_PACK_PUSH
-# define FB_PACK_POP FOLLY_PACK_POP
-#else
-# define FB_PACK_ATTR
-# define FB_PACK_PUSH
-# define FB_PACK_POP
-#endif
-
-#if FOLLY_HAVE_MALLOC_SIZE
-  extern "C" std::size_t malloc_size(const void*);
-# if !FOLLY_HAVE_MALLOC_USABLE_SIZE
-#  define malloc_usable_size malloc_size
-# endif
-# ifndef malloc_usable_size
-#  define malloc_usable_size malloc_size
-# endif
-#endif
+#include <folly/Portability.h>
+#include <folly/SmallLocks.h>
+#include <folly/portability/BitsFunctexcept.h>
+#include <folly/portability/Constexpr.h>
+#include <folly/portability/Malloc.h>
+#include <folly/portability/TypeTraits.h>
 
 // Ignore shadowing warnings within this file, so includers can use -Wshadow.
 #pragma GCC diagnostic push
@@ -342,7 +325,7 @@ namespace detail {
 }
 
 //////////////////////////////////////////////////////////////////////
-FB_PACK_PUSH
+FOLLY_PACK_PUSH
 template<class Value,
          std::size_t RequestedMaxInline    = 1,
          class PolicyA                     = void,
@@ -363,14 +346,10 @@ class small_vector
    * the user asks for less inlined elements than we can fit unioned
    * into our value_type*, we will inline more than they asked.)
    */
-  enum {
-    MaxInline = boost::mpl::max<
-                  boost::mpl::int_<sizeof(Value*) / sizeof(Value)>,
-                  boost::mpl::int_<RequestedMaxInline>
-                >::type::value
-  };
+  static constexpr std::size_t MaxInline{
+      constexpr_max(sizeof(Value*) / sizeof(Value), RequestedMaxInline)};
 
-public:
+ public:
   typedef std::size_t        size_type;
   typedef Value              value_type;
   typedef value_type&        reference;
@@ -382,7 +361,7 @@ public:
   typedef std::reverse_iterator<iterator>       reverse_iterator;
   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
 
-  explicit small_vector() {}
+  explicit small_vector() = default;
 
   small_vector(small_vector const& o) {
     auto n = o.size();
@@ -458,7 +437,7 @@ public:
   }
 
   static constexpr size_type max_size() {
-    return !BaseType::kShouldUseHeap ? MaxInline
+    return !BaseType::kShouldUseHeap ? static_cast<size_type>(MaxInline)
                                      : BaseType::policyMaxSize();
   }
 
@@ -658,6 +637,17 @@ public:
     emplaceBack(std::forward<Args>(args)...);
   }
 
+  void emplace_back(const value_type& t) {
+    push_back(t);
+  }
+  void emplace_back(value_type& t) {
+    push_back(t);
+  }
+
+  void emplace_back(value_type&& t) {
+    push_back(std::move(t));
+  }
+
   void push_back(value_type&& t) {
     if (capacity() == size()) {
       makeSize(std::max(size_type(2), 3 * size() / 2), &t, size());
@@ -668,9 +658,17 @@ public:
   }
 
   void push_back(value_type const& t) {
-    // Make a copy and forward to the rvalue value_type&& overload
-    // above.
-    push_back(value_type(t));
+    // TODO: we'd like to make use of makeSize (it can be optimized better,
+    // because it manipulates the internals)
+    // unfortunately the current implementation only supports moving from
+    // a supplied rvalue, and doing an extra move just to reuse it is a perf
+    // net loss
+    if (size() == capacity()) {// && isInside(&t)) {
+      value_type tmp(t);
+      emplaceBack(std::move(tmp));
+    } else {
+      emplaceBack(t);
+    }
   }
 
   void pop_back() {
@@ -784,14 +782,14 @@ public:
 
   reference at(size_type i) {
     if (i >= size()) {
-      throw std::out_of_range("index out of range");
+      std::__throw_out_of_range("index out of range");
     }
     return (*this)[i];
   }
 
   const_reference at(size_type i) const {
     if (i >= size()) {
-      throw std::out_of_range("index out of range");
+      std::__throw_out_of_range("index out of range");
     }
     return (*this)[i];
   }
@@ -809,13 +807,6 @@ private:
     this->setSize(size() + 1);
   }
 
-  /*
-   * Special case of emplaceBack for rvalue
-   */
-  void emplaceBack(value_type&& t) {
-    push_back(std::move(t));
-  }
-
   static iterator unconst(const_iterator it) {
     return const_cast<iterator>(it);
   }
@@ -871,7 +862,7 @@ private:
       // With iterators that only allow a single pass, we can't really
       // do anything sane here.
       while (first != last) {
-        push_back(*first++);
+        emplace_back(*first++);
       }
       return;
     }
@@ -1032,7 +1023,7 @@ private:
     InternalSizeType* getCapacity() {
       return &capacity_;
     }
-  } FB_PACK_ATTR;
+  } FOLLY_PACK_ATTR;
 
   struct HeapPtr {
     // Lower order bit of heap_ is used as flag to indicate whether capacity is
@@ -1044,17 +1035,23 @@ private:
       return static_cast<InternalSizeType*>(
         detail::pointerFlagClear(heap_));
     }
-  } FB_PACK_ATTR;
+  } FOLLY_PACK_ATTR;
 
-#if FOLLY_X64
-  typedef unsigned char InlineStorageType[sizeof(value_type) * MaxInline];
+#if (FOLLY_X64 || FOLLY_PPC64)
+  typedef unsigned char InlineStorageDataType[sizeof(value_type) * MaxInline];
 #else
   typedef typename std::aligned_storage<
     sizeof(value_type) * MaxInline,
     alignof(value_type)
-  >::type InlineStorageType;
+  >::type InlineStorageDataType;
 #endif
 
+  typedef typename std::conditional<
+    sizeof(value_type) * MaxInline != 0,
+    InlineStorageDataType,
+    void*
+  >::type InlineStorageType;
+
   static bool const kHasInlineCapacity =
     sizeof(HeapPtrWithCapacity) < sizeof(InlineStorageType);
 
@@ -1113,9 +1110,9 @@ private:
       auto vp = detail::pointerFlagClear(pdata_.heap_);
       free(vp);
     }
-  } FB_PACK_ATTR u;
-} FB_PACK_ATTR;
-FB_PACK_POP
+  } FOLLY_PACK_ATTR u;
+} FOLLY_PACK_ATTR;
+FOLLY_PACK_POP
 
 //////////////////////////////////////////////////////////////////////
 
@@ -1129,14 +1126,16 @@ void swap(small_vector<T,MaxInline,A,B,C>& a,
 
 //////////////////////////////////////////////////////////////////////
 
-}
+namespace detail {
 
-#pragma GCC diagnostic pop
+// Format support.
+template <class T, size_t M, class A, class B, class C>
+struct IndexableTraits<small_vector<T, M, A, B, C>>
+  : public IndexableTraitsSeq<small_vector<T, M, A, B, C>> {
+};
 
-#ifdef FB_PACK_ATTR
-# undef FB_PACK_ATTR
-# undef FB_PACK_PUSH
-# undef FB_PACK_POP
-#endif
+}  // namespace detail
 
-#endif
+}  // namespace folly
+
+#pragma GCC diagnostic pop