X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FFBVector.h;h=4a792af025d2e6dfbb1f7442218c3bb9537422d2;hb=61fbd6698139d3f797401da6350371c7afc4030c;hp=17f9f5ee01c74d019eb071974a09188e3853fe4e;hpb=ed8c80a0e0988e4ce687f51ca832a00e4a6b7930;p=folly.git diff --git a/folly/FBVector.h b/folly/FBVector.h index 17f9f5ee..4a792af0 100644 --- a/folly/FBVector.h +++ b/folly/FBVector.h @@ -800,7 +800,7 @@ private: template fbvector(ForwardIterator first, ForwardIterator last, const Allocator& a, std::forward_iterator_tag) - : impl_(std::distance(first, last), a) + : impl_(size_type(std::distance(first, last)), a) { M_uninitialized_copy_e(first, last); } template @@ -827,7 +827,7 @@ private: template void assign(ForwardIterator first, ForwardIterator last, std::forward_iterator_tag) { - const size_t newSize = std::distance(first, last); + const auto newSize = size_type(std::distance(first, last)); if (newSize > capacity()) { impl_.reset(newSize); M_uninitialized_copy_e(first, last); @@ -1004,7 +1004,7 @@ public: return; } if (impl_.b_) - M_deallocate(impl_.b_, impl_.z_ - impl_.b_); + M_deallocate(impl_.b_, size_type(impl_.z_ - impl_.b_)); impl_.z_ = newB + newCap; impl_.e_ = newB + (impl_.e_ - impl_.b_); impl_.b_ = newB; @@ -1276,7 +1276,7 @@ private: // we have the private section first because it defines some macros void make_window(iterator position, size_type n) { // The result is guaranteed to be non-negative, so use an unsigned type: - size_type tail = std::distance(position, impl_.e_); + size_type tail = size_type(std::distance(position, impl_.e_)); if (tail <= n) { relocate_move(position + n, position, impl_.e_); @@ -1343,117 +1343,125 @@ private: // we have the private section first because it defines some macros //--------------------------------------------------------------------------- // interface - #define FOLLY_FBVECTOR_INSERT_PRE(cpos, n) \ - if (n == 0) return (iterator)cpos; \ - bool at_end = cpos == cend(); \ - bool fresh = insert_use_fresh(at_end, n); \ - if (!at_end) { \ - if (!fresh) { - - // check for internal data (technically not required by the standard) - - #define FOLLY_FBVECTOR_INSERT_START(cpos, n) \ - } \ - assert(isValid(cpos)); \ - } \ - T* position = const_cast(cpos); \ - size_type idx = std::distance(impl_.b_, position); \ - T* b; \ - size_type newCap; /* intentionally uninitialized */ \ - \ - if (fresh) { \ - newCap = computeInsertCapacity(n); \ - b = M_allocate(newCap); \ - } else { \ - if (!at_end) { \ - make_window(position, n); \ - } else { \ - impl_.e_ += n; \ - } \ - b = impl_.b_; \ - } \ - \ - T* start = b + idx; \ - \ - try { \ - - // construct the inserted elements - - #define FOLLY_FBVECTOR_INSERT_TRY(cpos, n) \ - } catch (...) { \ - if (fresh) { \ - M_deallocate(b, newCap); \ - } else { \ - if (!at_end) { \ - undo_window(position, n); \ - } else { \ - impl_.e_ -= n; \ - } \ - } \ - throw; \ - } \ - \ - if (fresh) { \ - try { \ - wrap_frame(b, idx, n); \ - } catch (...) { \ - - - // delete the inserted elements (exception has been thrown) - - #define FOLLY_FBVECTOR_INSERT_END(cpos, n) \ - M_deallocate(b, newCap); \ - throw; \ - } \ - if (impl_.b_) M_deallocate(impl_.b_, capacity()); \ - impl_.set(b, size() + n, newCap); \ - return impl_.b_ + idx; \ - } else { \ - return position; \ - } \ + template < + typename IsInternalFunc, + typename InsertInternalFunc, + typename ConstructFunc, + typename DestroyFunc> + iterator do_real_insert( + const_iterator cpos, + size_type n, + IsInternalFunc&& isInternalFunc, + InsertInternalFunc&& insertInternalFunc, + ConstructFunc&& constructFunc, + DestroyFunc&& destroyFunc) { + if (n == 0) { + return iterator(cpos); + } + bool at_end = cpos == cend(); + bool fresh = insert_use_fresh(at_end, n); + if (!at_end) { + if (!fresh && isInternalFunc()) { + // check for internal data (technically not required by the standard) + return insertInternalFunc(); + } + assert(isValid(cpos)); + } + T* position = const_cast(cpos); + size_type idx = size_type(std::distance(impl_.b_, position)); + T* b; + size_type newCap; /* intentionally uninitialized */ - //--------------------------------------------------------------------------- - // insert functions -public: + if (fresh) { + newCap = computeInsertCapacity(n); + b = M_allocate(newCap); + } else { + if (!at_end) { + make_window(position, n); + } else { + impl_.e_ += n; + } + b = impl_.b_; + } + + T* start = b + idx; + try { + // construct the inserted elements + constructFunc(start); + } catch (...) { + if (fresh) { + M_deallocate(b, newCap); + } else { + if (!at_end) { + undo_window(position, n); + } else { + impl_.e_ -= n; + } + } + throw; + } + + if (fresh) { + try { + wrap_frame(b, idx, n); + } catch (...) { + // delete the inserted elements (exception has been thrown) + destroyFunc(start); + M_deallocate(b, newCap); + throw; + } + if (impl_.b_) { + M_deallocate(impl_.b_, capacity()); + } + impl_.set(b, size() + n, newCap); + return impl_.b_ + idx; + } else { + return position; + } + } + public: template iterator emplace(const_iterator cpos, Args&&... args) { - FOLLY_FBVECTOR_INSERT_PRE(cpos, 1) - FOLLY_FBVECTOR_INSERT_START(cpos, 1) - M_construct(start, std::forward(args)...); - FOLLY_FBVECTOR_INSERT_TRY(cpos, 1) - M_destroy(start); - FOLLY_FBVECTOR_INSERT_END(cpos, 1) + return do_real_insert( + cpos, + 1, + [&] { return false; }, + [&] { return iterator{}; }, + [&](iterator start) { + M_construct(start, std::forward(args)...); + }, + [&](iterator start) { M_destroy(start); }); } iterator insert(const_iterator cpos, const T& value) { - FOLLY_FBVECTOR_INSERT_PRE(cpos, 1) - if (dataIsInternal(value)) return insert(cpos, T(value)); - FOLLY_FBVECTOR_INSERT_START(cpos, 1) - M_construct(start, value); - FOLLY_FBVECTOR_INSERT_TRY(cpos, 1) - M_destroy(start); - FOLLY_FBVECTOR_INSERT_END(cpos, 1) + return do_real_insert( + cpos, + 1, + [&] { return dataIsInternal(value); }, + [&] { return insert(cpos, T(value)); }, + [&](iterator start) { M_construct(start, value); }, + [&](iterator start) { M_destroy(start); }); } iterator insert(const_iterator cpos, T&& value) { - FOLLY_FBVECTOR_INSERT_PRE(cpos, 1) - if (dataIsInternal(value)) return insert(cpos, T(std::move(value))); - FOLLY_FBVECTOR_INSERT_START(cpos, 1) - M_construct(start, std::move(value)); - FOLLY_FBVECTOR_INSERT_TRY(cpos, 1) - M_destroy(start); - FOLLY_FBVECTOR_INSERT_END(cpos, 1) + return do_real_insert( + cpos, + 1, + [&] { return dataIsInternal(value); }, + [&] { return insert(cpos, T(std::move(value))); }, + [&](iterator start) { M_construct(start, std::move(value)); }, + [&](iterator start) { M_destroy(start); }); } iterator insert(const_iterator cpos, size_type n, VT value) { - FOLLY_FBVECTOR_INSERT_PRE(cpos, n) - if (dataIsInternalAndNotVT(value)) return insert(cpos, n, T(value)); - FOLLY_FBVECTOR_INSERT_START(cpos, n) - D_uninitialized_fill_n_a(start, n, value); - FOLLY_FBVECTOR_INSERT_TRY(cpos, n) - D_destroy_range_a(start, start + n); - FOLLY_FBVECTOR_INSERT_END(cpos, n) + return do_real_insert( + cpos, + n, + [&] { return dataIsInternalAndNotVT(value); }, + [&] { return insert(cpos, n, T(value)); }, + [&](iterator start) { D_uninitialized_fill_n_a(start, n, value); }, + [&](iterator start) { D_destroy_range_a(start, start + n); }); } template iterator insert(const_iterator cpos, FIt first, FIt last, std::forward_iterator_tag) { - size_type n = std::distance(first, last); - FOLLY_FBVECTOR_INSERT_PRE(cpos, n) - FOLLY_FBVECTOR_INSERT_START(cpos, n) - D_uninitialized_copy_a(start, first, last); - FOLLY_FBVECTOR_INSERT_TRY(cpos, n) - D_destroy_range_a(start, start + n); - FOLLY_FBVECTOR_INSERT_END(cpos, n) + size_type n = size_type(std::distance(first, last)); + return do_real_insert( + cpos, + n, + [&] { return false; }, + [&] { return iterator{}; }, + [&](iterator start) { D_uninitialized_copy_a(start, first, last); }, + [&](iterator start) { D_destroy_range_a(start, start + n); }); } template