X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2Fsmall_vector.h;h=4ef59b67e96565ab86837917c2c3d863ffee7dbf;hp=042961bc4a7ba15a39c82563b377f14815235fa8;hb=96791c4516497b4ea2ad08af12e4267bd1c4e796;hpb=71b5c88168380fc8c93683bd153e16d34e654e8c diff --git a/folly/small_vector.h b/folly/small_vector.h index 042961bc..4ef59b67 100644 --- a/folly/small_vector.h +++ b/folly/small_vector.h @@ -1,5 +1,5 @@ /* - * Copyright 2016 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. @@ -47,8 +47,11 @@ #include #include #include +#include +#include #include #include +#include // Ignore shadowing warnings within this file, so includers can use -Wshadow. #pragma GCC diagnostic push @@ -344,12 +347,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 = - constexpr_max(sizeof(Value*) / sizeof(Value), RequestedMaxInline), - }; + 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; @@ -393,8 +394,12 @@ public: constructImpl(il.begin(), il.end(), std::false_type()); } - explicit small_vector(size_type n, value_type const& t = value_type()) { - doConstruct(n, t); + explicit small_vector(size_type n) { + doConstruct(n, [&](void* p) { new (p) value_type(); }); + } + + small_vector(size_type n, value_type const& t) { + doConstruct(n, [&](void* p) { new (p) value_type(t); }); } template @@ -437,7 +442,7 @@ public: } static constexpr size_type max_size() { - return !BaseType::kShouldUseHeap ? MaxInline + return !BaseType::kShouldUseHeap ? static_cast(MaxInline) : BaseType::policyMaxSize(); } @@ -782,14 +787,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]; } @@ -882,13 +887,12 @@ private: } } - void doConstruct(size_type n, value_type const& val) { + template + void doConstruct(size_type n, InitFunc&& func) { makeSize(n); this->setSize(n); try { - detail::populateMemForward(data(), n, - [&] (void* p) { new (p) value_type(val); } - ); + detail::populateMemForward(data(), n, std::forward(func)); } catch (...) { if (this->isExtern()) { u.freeHeap(); @@ -900,7 +904,7 @@ private: // The true_type means we should forward to the size_t,value_type // overload. void constructImpl(size_type n, value_type const& val, std::true_type) { - doConstruct(n, val); + doConstruct(n, [&](void* p) { new (p) value_type(val); }); } void makeSize(size_type size, value_type* v = nullptr) { @@ -1038,14 +1042,20 @@ private: } FOLLY_PACK_ATTR; #if (FOLLY_X64 || FOLLY_PPC64) - typedef unsigned char InlineStorageType[sizeof(value_type) * MaxInline]; + 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);