/*
 * Copyright 2015 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Nicholas Ormrod      (njormrod)
 * Andrei Alexandrescu  (aalexandre)
 *
 * FBVector is Facebook's drop-in implementation of std::vector. It has special
 * optimizations for use with relocatable types and jemalloc.
 */

#ifndef FOLLY_FBVECTOR_H
#define FOLLY_FBVECTOR_H

//=============================================================================
// headers

#include <algorithm>
#include <cassert>
#include <iterator>
#include <memory>
#include <stdexcept>
#include <type_traits>
#include <utility>

#include <folly/FormatTraits.h>
#include <folly/Likely.h>
#include <folly/Malloc.h>
#include <folly/Traits.h>

#include <boost/operators.hpp>

//=============================================================================
// forward declaration

namespace folly {
  template <class T, class Allocator = std::allocator<T>>
  class fbvector;
}

//=============================================================================
// unrolling

#define FOLLY_FBV_UNROLL_PTR(first, last, OP) do {  \
  for (; (last) - (first) >= 4; (first) += 4) {     \
    OP(((first) + 0));                              \
    OP(((first) + 1));                              \
    OP(((first) + 2));                              \
    OP(((first) + 3));                              \
  }                                                 \
  for (; (first) != (last); ++(first)) OP((first)); \
} while(0);

//=============================================================================
///////////////////////////////////////////////////////////////////////////////
//                                                                           //
//                              fbvector class                               //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

namespace folly {

template <class T, class Allocator>
class fbvector : private boost::totally_ordered<fbvector<T, Allocator>> {

  //===========================================================================
  //---------------------------------------------------------------------------
  // implementation
private:

  typedef std::allocator_traits<Allocator> A;

  struct Impl : public Allocator {
    // typedefs
    typedef typename A::pointer pointer;
    typedef typename A::size_type size_type;

    // data
    pointer b_, e_, z_;

    // constructors
    Impl() : Allocator(), b_(nullptr), e_(nullptr), z_(nullptr) {}
    /* implicit */ Impl(const Allocator& a)
      : Allocator(a), b_(nullptr), e_(nullptr), z_(nullptr) {}
    /* implicit */ Impl(Allocator&& a)
      : Allocator(std::move(a)), b_(nullptr), e_(nullptr), z_(nullptr) {}

    /* implicit */ Impl(size_type n, const Allocator& a = Allocator())
      : Allocator(a)
      { init(n); }

    Impl(Impl&& other) noexcept
      : Allocator(std::move(other)),
        b_(other.b_), e_(other.e_), z_(other.z_)
      { other.b_ = other.e_ = other.z_ = nullptr; }

    // destructor
    ~Impl() {
      destroy();
    }

    // allocation
    // note that 'allocate' and 'deallocate' are inherited from Allocator
    T* D_allocate(size_type n) {
      if (usingStdAllocator::value) {
        return static_cast<T*>(malloc(n * sizeof(T)));
      } else {
        return std::allocator_traits<Allocator>::allocate(*this, n);
      }
    }

    void D_deallocate(T* p, size_type n) noexcept {
      if (usingStdAllocator::value) {
        free(p);
      } else {
        std::allocator_traits<Allocator>::deallocate(*this, p, n);
      }
    }

    // helpers
    void swapData(Impl& other) {
      std::swap(b_, other.b_);
      std::swap(e_, other.e_);
      std::swap(z_, other.z_);
    }

    // data ops
    inline void destroy() noexcept {
      if (b_) {
        // THIS DISPATCH CODE IS DUPLICATED IN fbvector::D_destroy_range_a.
        // It has been inlined here for speed. It calls the static fbvector
        //  methods to perform the actual destruction.
        if (usingStdAllocator::value) {
          S_destroy_range(b_, e_);
        } else {
          S_destroy_range_a(*this, b_, e_);
        }

        D_deallocate(b_, z_ - b_);
      }
    }

    void init(size_type n) {
      if (UNLIKELY(n == 0)) {
        b_ = e_ = z_ = nullptr;
      } else {
        size_type sz = folly::goodMallocSize(n * sizeof(T)) / sizeof(T);
        b_ = D_allocate(sz);
        e_ = b_;
        z_ = b_ + sz;
      }
    }

    void
    set(pointer newB, size_type newSize, size_type newCap) {
      z_ = newB + newCap;
      e_ = newB + newSize;
      b_ = newB;
    }

    void reset(size_type newCap) {
      destroy();
      try {
        init(newCap);
      } catch (...) {
        init(0);
        throw;
      }
    }
    void reset() { // same as reset(0)
      destroy();
      b_ = e_ = z_ = nullptr;
    }
  } impl_;

  static void swap(Impl& a, Impl& b) {
    using std::swap;
    if (!usingStdAllocator::value) swap<Allocator>(a, b);
    a.swapData(b);
  }

  //===========================================================================
  //---------------------------------------------------------------------------
  // types and constants
public:

  typedef T                                           value_type;
  typedef value_type&                                 reference;
  typedef const value_type&                           const_reference;
  typedef T*                                          iterator;
  typedef const T*                                    const_iterator;
  typedef size_t                                      size_type;
  typedef typename std::make_signed<size_type>::type  difference_type;
  typedef Allocator                                   allocator_type;
  typedef typename A::pointer                         pointer;
  typedef typename A::const_pointer                   const_pointer;
  typedef std::reverse_iterator<iterator>             reverse_iterator;
  typedef std::reverse_iterator<const_iterator>       const_reverse_iterator;

private:

  typedef std::integral_constant<bool,
      boost::has_trivial_copy_constructor<T>::value &&
      sizeof(T) <= 16 // don't force large structures to be passed by value
    > should_pass_by_value;
  typedef typename std::conditional<
      should_pass_by_value::value, T, const T&>::type VT;
  typedef typename std::conditional<
      should_pass_by_value::value, T, T&&>::type MT;

  typedef std::integral_constant<bool,
      std::is_same<Allocator, std::allocator<T>>::value> usingStdAllocator;
  typedef std::integral_constant<bool,
      usingStdAllocator::value ||
      A::propagate_on_container_move_assignment::value> moveIsSwap;

  //===========================================================================
  //---------------------------------------------------------------------------
  // allocator helpers
private:

  //---------------------------------------------------------------------------
  // allocate

  T* M_allocate(size_type n) {
    return impl_.D_allocate(n);
  }

  //---------------------------------------------------------------------------
  // deallocate

  void M_deallocate(T* p, size_type n) noexcept {
    impl_.D_deallocate(p, n);
  }

  //---------------------------------------------------------------------------
  // construct

  // GCC is very sensitive to the exact way that construct is called. For
  //  that reason there are several different specializations of construct.

  template <typename U, typename... Args>
  void M_construct(U* p, Args&&... args) {
    if (usingStdAllocator::value) {
      new (p) U(std::forward<Args>(args)...);
    } else {
      std::allocator_traits<Allocator>::construct(
        impl_, p, std::forward<Args>(args)...);
    }
  }

  template <typename U, typename... Args>
  static void S_construct(U* p, Args&&... args) {
    new (p) U(std::forward<Args>(args)...);
  }

  template <typename U, typename... Args>
  static void S_construct_a(Allocator& a, U* p, Args&&... args) {
    std::allocator_traits<Allocator>::construct(
      a, p, std::forward<Args>(args)...);
  }

  // scalar optimization
  // TODO we can expand this optimization to: default copyable and assignable
  template <typename U, typename Enable = typename
    std::enable_if<std::is_scalar<U>::value>::type>
  void M_construct(U* p, U arg) {
    if (usingStdAllocator::value) {
      *p = arg;
    } else {
      std::allocator_traits<Allocator>::construct(impl_, p, arg);
    }
  }

  template <typename U, typename Enable = typename
    std::enable_if<std::is_scalar<U>::value>::type>
  static void S_construct(U* p, U arg) {
    *p = arg;
  }

  template <typename U, typename Enable = typename
    std::enable_if<std::is_scalar<U>::value>::type>
  static void S_construct_a(Allocator& a, U* p, U arg) {
    std::allocator_traits<Allocator>::construct(a, p, arg);
  }

  // const& optimization
  template <typename U, typename Enable = typename
    std::enable_if<!std::is_scalar<U>::value>::type>
  void M_construct(U* p, const U& value) {
    if (usingStdAllocator::value) {
      new (p) U(value);
    } else {
      std::allocator_traits<Allocator>::construct(impl_, p, value);
    }
  }

  template <typename U, typename Enable = typename
    std::enable_if<!std::is_scalar<U>::value>::type>
  static void S_construct(U* p, const U& value) {
    new (p) U(value);
  }

  template <typename U, typename Enable = typename
    std::enable_if<!std::is_scalar<U>::value>::type>
  static void S_construct_a(Allocator& a, U* p, const U& value) {
    std::allocator_traits<Allocator>::construct(a, p, value);
  }

  //---------------------------------------------------------------------------
  // destroy

  void M_destroy(T* p) noexcept {
    if (usingStdAllocator::value) {
      if (!boost::has_trivial_destructor<T>::value) p->~T();
    } else {
      std::allocator_traits<Allocator>::destroy(impl_, p);
    }
  }

  //===========================================================================
  //---------------------------------------------------------------------------
  // algorithmic helpers
private:

  //---------------------------------------------------------------------------
  // destroy_range

  // wrappers
  void M_destroy_range_e(T* pos) noexcept {
    D_destroy_range_a(pos, impl_.e_);
    impl_.e_ = pos;
  }

  // dispatch
  // THIS DISPATCH CODE IS DUPLICATED IN IMPL. SEE IMPL FOR DETAILS.
  void D_destroy_range_a(T* first, T* last) noexcept {
    if (usingStdAllocator::value) {
      S_destroy_range(first, last);
    } else {
      S_destroy_range_a(impl_, first, last);
    }
  }

  // allocator
  static void S_destroy_range_a(Allocator& a, T* first, T* last) noexcept {
    for (; first != last; ++first)
      std::allocator_traits<Allocator>::destroy(a, first);
  }

  // optimized
  static void S_destroy_range(T* first, T* last) noexcept {
    if (!boost::has_trivial_destructor<T>::value) {
      // EXPERIMENTAL DATA on fbvector<vector<int>> (where each vector<int> has
      //  size 0).
      // The unrolled version seems to work faster for small to medium sized
      //  fbvectors. It gets a 10% speedup on fbvectors of size 1024, 64, and
      //  16.
      // The simple loop version seems to work faster for large fbvectors. The
      //  unrolled version is about 6% slower on fbvectors on size 16384.
      // The two methods seem tied for very large fbvectors. The unrolled
      //  version is about 0.5% slower on size 262144.

      // for (; first != last; ++first) first->~T();
      #define FOLLY_FBV_OP(p) (p)->~T()
      FOLLY_FBV_UNROLL_PTR(first, last, FOLLY_FBV_OP)
      #undef FOLLY_FBV_OP
    }
  }

  //---------------------------------------------------------------------------
  // uninitialized_fill_n

  // wrappers
  void M_uninitialized_fill_n_e(size_type sz) {
    D_uninitialized_fill_n_a(impl_.e_, sz);
    impl_.e_ += sz;
  }

  void M_uninitialized_fill_n_e(size_type sz, VT value) {
    D_uninitialized_fill_n_a(impl_.e_, sz, value);
    impl_.e_ += sz;
  }

  // dispatch
  void D_uninitialized_fill_n_a(T* dest, size_type sz) {
    if (usingStdAllocator::value) {
      S_uninitialized_fill_n(dest, sz);
    } else {
      S_uninitialized_fill_n_a(impl_, dest, sz);
    }
  }

  void D_uninitialized_fill_n_a(T* dest, size_type sz, VT value) {
    if (usingStdAllocator::value) {
      S_uninitialized_fill_n(dest, sz, value);
    } else {
      S_uninitialized_fill_n_a(impl_, dest, sz, value);
    }
  }

  // allocator
  template <typename... Args>
  static void S_uninitialized_fill_n_a(Allocator& a, T* dest,
                                       size_type sz, Args&&... args) {
    auto b = dest;
    auto e = dest + sz;
    try {
      for (; b != e; ++b)
        std::allocator_traits<Allocator>::construct(a, b,
          std::forward<Args>(args)...);
    } catch (...) {
      S_destroy_range_a(a, dest, b);
      throw;
    }
  }

  // optimized
  static void S_uninitialized_fill_n(T* dest, size_type n) {
    if (folly::IsZeroInitializable<T>::value) {
      std::memset(dest, 0, sizeof(T) * n);
    } else {
      auto b = dest;
      auto e = dest + n;
      try {
        for (; b != e; ++b) S_construct(b);
      } catch (...) {
        --b;
        for (; b >= dest; --b) b->~T();
        throw;
      }
    }
  }

  static void S_uninitialized_fill_n(T* dest, size_type n, const T& value) {
    auto b = dest;
    auto e = dest + n;
    try {
      for (; b != e; ++b) S_construct(b, value);
    } catch (...) {
      S_destroy_range(dest, b);
      throw;
    }
  }

  //---------------------------------------------------------------------------
  // uninitialized_copy

  // it is possible to add an optimization for the case where
  // It = move(T*) and IsRelocatable<T> and Is0Initiailizable<T>

  // wrappers
  template <typename It>
  void M_uninitialized_copy_e(It first, It last) {
    D_uninitialized_copy_a(impl_.e_, first, last);
    impl_.e_ += std::distance(first, last);
  }

  template <typename It>
  void M_uninitialized_move_e(It first, It last) {
    D_uninitialized_move_a(impl_.e_, first, last);
    impl_.e_ += std::distance(first, last);
  }

  // dispatch
  template <typename It>
  void D_uninitialized_copy_a(T* dest, It first, It last) {
    if (usingStdAllocator::value) {
      if (folly::IsTriviallyCopyable<T>::value) {
        S_uninitialized_copy_bits(dest, first, last);
      } else {
        S_uninitialized_copy(dest, first, last);
      }
    } else {
      S_uninitialized_copy_a(impl_, dest, first, last);
    }
  }

  template <typename It>
  void D_uninitialized_move_a(T* dest, It first, It last) {
    D_uninitialized_copy_a(dest,
      std::make_move_iterator(first), std::make_move_iterator(last));
  }

  // allocator
  template <typename It>
  static void
  S_uninitialized_copy_a(Allocator& a, T* dest, It first, It last) {
    auto b = dest;
    try {
      for (; first != last; ++first, ++b)
        std::allocator_traits<Allocator>::construct(a, b, *first);
    } catch (...) {
      S_destroy_range_a(a, dest, b);
      throw;
    }
  }

  // optimized
  template <typename It>
  static void S_uninitialized_copy(T* dest, It first, It last) {
    auto b = dest;
    try {
      for (; first != last; ++first, ++b)
        S_construct(b, *first);
    } catch (...) {
      S_destroy_range(dest, b);
      throw;
    }
  }

  static void
  S_uninitialized_copy_bits(T* dest, const T* first, const T* last) {
    std::memcpy((void*)dest, (void*)first, (last - first) * sizeof(T));
  }

  static void
  S_uninitialized_copy_bits(T* dest, std::move_iterator<T*> first,
                       std::move_iterator<T*> last) {
    T* bFirst = first.base();
    T* bLast = last.base();
    std::memcpy((void*)dest, (void*)bFirst, (bLast - bFirst) * sizeof(T));
  }

  template <typename It>
  static void
  S_uninitialized_copy_bits(T* dest, It first, It last) {
    S_uninitialized_copy(dest, first, last);
  }

  //---------------------------------------------------------------------------
  // copy_n

  // This function is "unsafe": it assumes that the iterator can be advanced at
  //  least n times. However, as a private function, that unsafety is managed
  //  wholly by fbvector itself.

  template <typename It>
  static It S_copy_n(T* dest, It first, size_type n) {
    auto e = dest + n;
    for (; dest != e; ++dest, ++first) *dest = *first;
    return first;
  }

  static const T* S_copy_n(T* dest, const T* first, size_type n) {
    if (folly::IsTriviallyCopyable<T>::value) {
      std::memcpy((void*)dest, (void*)first, n * sizeof(T));
      return first + n;
    } else {
      return S_copy_n<const T*>(dest, first, n);
    }
  }

  static std::move_iterator<T*>
  S_copy_n(T* dest, std::move_iterator<T*> mIt, size_type n) {
    if (folly::IsTriviallyCopyable<T>::value) {
      T* first = mIt.base();
      std::memcpy((void*)dest, (void*)first, n * sizeof(T));
      return std::make_move_iterator(first + n);
    } else {
      return S_copy_n<std::move_iterator<T*>>(dest, mIt, n);
    }
  }

  //===========================================================================
  //---------------------------------------------------------------------------
  // relocation helpers
private:

  // Relocation is divided into three parts:
  //
  //  1: relocate_move
  //     Performs the actual movement of data from point a to point b.
  //
  //  2: relocate_done
  //     Destroys the old data.
  //
  //  3: relocate_undo
  //     Destoys the new data and restores the old data.
  //
  // The three steps are used because there may be an exception after part 1
  //  has completed. If that is the case, then relocate_undo can nullify the
  //  initial move. Otherwise, relocate_done performs the last bit of tidying
  //  up.
  //
  // The relocation trio may use either memcpy, move, or copy. It is decided
  //  by the following case statement:
  //
  //  IsRelocatable && usingStdAllocator    -> memcpy
  //  has_nothrow_move && usingStdAllocator -> move
  //  cannot copy                           -> move
  //  default                               -> copy
  //
  // If the class is non-copyable then it must be movable. However, if the
  //  move constructor is not noexcept, i.e. an error could be thrown, then
  //  relocate_undo will be unable to restore the old data, for fear of a
  //  second exception being thrown. This is a known and unavoidable
  //  deficiency. In lieu of a strong exception guarantee, relocate_undo does
  //  the next best thing: it provides a weak exception guarantee by
  //  destorying the new data, but leaving the old data in an indeterminate
  //  state. Note that that indeterminate state will be valid, since the
  //  old data has not been destroyed; it has merely been the source of a
  //  move, which is required to leave the source in a valid state.

  // wrappers
  void M_relocate(T* newB) {
    relocate_move(newB, impl_.b_, impl_.e_);
    relocate_done(newB, impl_.b_, impl_.e_);
  }

  // dispatch type trait
  typedef std::integral_constant<bool,
      folly::IsRelocatable<T>::value && usingStdAllocator::value
    > relocate_use_memcpy;

  typedef std::integral_constant<bool,
      (std::is_nothrow_move_constructible<T>::value
       && usingStdAllocator::value)
      || !std::is_copy_constructible<T>::value
    > relocate_use_move;

  // move
  void relocate_move(T* dest, T* first, T* last) {
    relocate_move_or_memcpy(dest, first, last, relocate_use_memcpy());
  }

  void relocate_move_or_memcpy(T* dest, T* first, T* last, std::true_type) {
    std::memcpy((void*)dest, (void*)first, (last - first) * sizeof(T));
  }

  void relocate_move_or_memcpy(T* dest, T* first, T* last, std::false_type) {
    relocate_move_or_copy(dest, first, last, relocate_use_move());
  }

  void relocate_move_or_copy(T* dest, T* first, T* last, std::true_type) {
    D_uninitialized_move_a(dest, first, last);
  }

  void relocate_move_or_copy(T* dest, T* first, T* last, std::false_type) {
    D_uninitialized_copy_a(dest, first, last);
  }

  // done
  void relocate_done(T* /*dest*/, T* first, T* last) noexcept {
    if (folly::IsRelocatable<T>::value && usingStdAllocator::value) {
      // used memcpy; data has been relocated, do not call destructor
    } else {
      D_destroy_range_a(first, last);
    }
  }

  // undo
  void relocate_undo(T* dest, T* first, T* last) noexcept {
    if (folly::IsRelocatable<T>::value && usingStdAllocator::value) {
      // used memcpy, old data is still valid, nothing to do
    } else if (std::is_nothrow_move_constructible<T>::value &&
               usingStdAllocator::value) {
      // noexcept move everything back, aka relocate_move
      relocate_move(first, dest, dest + (last - first));
    } else if (!std::is_copy_constructible<T>::value) {
      // weak guarantee
      D_destroy_range_a(dest, dest + (last - first));
    } else {
      // used copy, old data is still valid
      D_destroy_range_a(dest, dest + (last - first));
    }
  }


  //===========================================================================
  //---------------------------------------------------------------------------
  // construct/copy/destroy
public:

  fbvector() = default;

  explicit fbvector(const Allocator& a) : impl_(a) {}

  explicit fbvector(size_type n, const Allocator& a = Allocator())
    : impl_(n, a)
    { M_uninitialized_fill_n_e(n); }

  fbvector(size_type n, VT value, const Allocator& a = Allocator())
    : impl_(n, a)
    { M_uninitialized_fill_n_e(n, value); }

  template <class It, class Category = typename
            std::iterator_traits<It>::iterator_category>
  fbvector(It first, It last, const Allocator& a = Allocator())
    : fbvector(first, last, a, Category()) {}

  fbvector(const fbvector& other)
    : impl_(other.size(), A::select_on_container_copy_construction(other.impl_))
    { M_uninitialized_copy_e(other.begin(), other.end()); }

  fbvector(fbvector&& other) noexcept : impl_(std::move(other.impl_)) {}

  fbvector(const fbvector& other, const Allocator& a)
    : fbvector(other.begin(), other.end(), a) {}

  /* may throw */ fbvector(fbvector&& other, const Allocator& a) : impl_(a) {
    if (impl_ == other.impl_) {
      impl_.swapData(other.impl_);
    } else {
      impl_.init(other.size());
      M_uninitialized_move_e(other.begin(), other.end());
    }
  }

  fbvector(std::initializer_list<T> il, const Allocator& a = Allocator())
    : fbvector(il.begin(), il.end(), a) {}

  ~fbvector() = default; // the cleanup occurs in impl_

  fbvector& operator=(const fbvector& other) {
    if (UNLIKELY(this == &other)) return *this;

    if (!usingStdAllocator::value &&
        A::propagate_on_container_copy_assignment::value) {
      if (impl_ != other.impl_) {
        // can't use other's different allocator to clean up self
        impl_.reset();
      }
      (Allocator&)impl_ = (Allocator&)other.impl_;
    }

    assign(other.begin(), other.end());
    return *this;
  }

  fbvector& operator=(fbvector&& other) {
    if (UNLIKELY(this == &other)) return *this;
    moveFrom(std::move(other), moveIsSwap());
    return *this;
  }

  fbvector& operator=(std::initializer_list<T> il) {
    assign(il.begin(), il.end());
    return *this;
  }

  template <class It, class Category = typename
            std::iterator_traits<It>::iterator_category>
  void assign(It first, It last) {
    assign(first, last, Category());
  }

  void assign(size_type n, VT value) {
    if (n > capacity()) {
      // Not enough space. Do not reserve in place, since we will
      // discard the old values anyways.
      if (dataIsInternalAndNotVT(value)) {
        T copy(std::move(value));
        impl_.reset(n);
        M_uninitialized_fill_n_e(n, copy);
      } else {
        impl_.reset(n);
        M_uninitialized_fill_n_e(n, value);
      }
    } else if (n <= size()) {
      auto newE = impl_.b_ + n;
      std::fill(impl_.b_, newE, value);
      M_destroy_range_e(newE);
    } else {
      std::fill(impl_.b_, impl_.e_, value);
      M_uninitialized_fill_n_e(n - size(), value);
    }
  }

  void assign(std::initializer_list<T> il) {
    assign(il.begin(), il.end());
  }

  allocator_type get_allocator() const noexcept {
    return impl_;
  }

private:

  // contract dispatch for iterator types fbvector(It first, It last)
  template <class ForwardIterator>
  fbvector(ForwardIterator first, ForwardIterator last,
           const Allocator& a, std::forward_iterator_tag)
    : impl_(std::distance(first, last), a)
    { M_uninitialized_copy_e(first, last); }

  template <class InputIterator>
  fbvector(InputIterator first, InputIterator last,
           const Allocator& a, std::input_iterator_tag)
    : impl_(a)
    { for (; first != last; ++first) emplace_back(*first); }

  // contract dispatch for allocator movement in operator=(fbvector&&)
  void
  moveFrom(fbvector&& other, std::true_type) {
    swap(impl_, other.impl_);
  }
  void moveFrom(fbvector&& other, std::false_type) {
    if (impl_ == other.impl_) {
      impl_.swapData(other.impl_);
    } else {
      impl_.reset(other.size());
      M_uninitialized_move_e(other.begin(), other.end());
    }
  }

  // contract dispatch for iterator types in assign(It first, It last)
  template <class ForwardIterator>
  void assign(ForwardIterator first, ForwardIterator last,
              std::forward_iterator_tag) {
    const size_t newSize = std::distance(first, last);
    if (newSize > capacity()) {
      impl_.reset(newSize);
      M_uninitialized_copy_e(first, last);
    } else if (newSize <= size()) {
      auto newEnd = std::copy(first, last, impl_.b_);
      M_destroy_range_e(newEnd);
    } else {
      auto mid = S_copy_n(impl_.b_, first, size());
      M_uninitialized_copy_e<decltype(last)>(mid, last);
    }
  }

  template <class InputIterator>
  void assign(InputIterator first, InputIterator last,
              std::input_iterator_tag) {
    auto p = impl_.b_;
    for (; first != last && p != impl_.e_; ++first, ++p) {
      *p = *first;
    }
    if (p != impl_.e_) {
      M_destroy_range_e(p);
    } else {
      for (; first != last; ++first) emplace_back(*first);
    }
  }

  // contract dispatch for aliasing under VT optimization
  bool dataIsInternalAndNotVT(const T& t) {
    if (should_pass_by_value::value) return false;
    return dataIsInternal(t);
  }
  bool dataIsInternal(const T& t) {
    return UNLIKELY(impl_.b_ <= std::addressof(t) &&
                    std::addressof(t) < impl_.e_);
  }


  //===========================================================================
  //---------------------------------------------------------------------------
  // iterators
public:

  iterator begin() noexcept {
    return impl_.b_;
  }
  const_iterator begin() const noexcept {
    return impl_.b_;
  }
  iterator end() noexcept {
    return impl_.e_;
  }
  const_iterator end() const noexcept {
    return impl_.e_;
  }
  reverse_iterator rbegin() noexcept {
    return reverse_iterator(end());
  }
  const_reverse_iterator rbegin() const noexcept {
    return const_reverse_iterator(end());
  }
  reverse_iterator rend() noexcept {
    return reverse_iterator(begin());
  }
  const_reverse_iterator rend() const noexcept {
    return const_reverse_iterator(begin());
  }

  const_iterator cbegin() const noexcept {
    return impl_.b_;
  }
  const_iterator cend() const noexcept {
    return impl_.e_;
  }
  const_reverse_iterator crbegin() const noexcept {
    return const_reverse_iterator(end());
  }
  const_reverse_iterator crend() const noexcept {
    return const_reverse_iterator(begin());
  }

  //===========================================================================
  //---------------------------------------------------------------------------
  // capacity
public:

  size_type size() const noexcept {
    return impl_.e_ - impl_.b_;
  }

  size_type max_size() const noexcept {
    // good luck gettin' there
    return ~size_type(0);
  }

  void resize(size_type n) {
    if (n <= size()) {
      M_destroy_range_e(impl_.b_ + n);
    } else {
      reserve(n);
      M_uninitialized_fill_n_e(n - size());
    }
  }

  void resize(size_type n, VT t) {
    if (n <= size()) {
      M_destroy_range_e(impl_.b_ + n);
    } else if (dataIsInternalAndNotVT(t) && n > capacity()) {
      T copy(t);
      reserve(n);
      M_uninitialized_fill_n_e(n - size(), copy);
    } else {
      reserve(n);
      M_uninitialized_fill_n_e(n - size(), t);
    }
  }

  size_type capacity() const noexcept {
    return impl_.z_ - impl_.b_;
  }

  bool empty() const noexcept {
    return impl_.b_ == impl_.e_;
  }

  void reserve(size_type n) {
    if (n <= capacity()) return;
    if (impl_.b_ && reserve_in_place(n)) return;

    auto newCap = folly::goodMallocSize(n * sizeof(T)) / sizeof(T);
    auto newB = M_allocate(newCap);
    try {
      M_relocate(newB);
    } catch (...) {
      M_deallocate(newB, newCap);
      throw;
    }
    if (impl_.b_)
      M_deallocate(impl_.b_, impl_.z_ - impl_.b_);
    impl_.z_ = newB + newCap;
    impl_.e_ = newB + (impl_.e_ - impl_.b_);
    impl_.b_ = newB;
  }

  void shrink_to_fit() noexcept {
    auto const newCapacityBytes = folly::goodMallocSize(size() * sizeof(T));
    auto const newCap = newCapacityBytes / sizeof(T);
    auto const oldCap = capacity();

    if (newCap >= oldCap) return;

    void* p = impl_.b_;
    // xallocx() will shrink to precisely newCapacityBytes (which was generated
    // by goodMallocSize()) if it successfully shrinks in place.
    if ((usingJEMalloc() && usingStdAllocator::value) &&
        newCapacityBytes >= folly::jemallocMinInPlaceExpandable &&
        xallocx(p, newCapacityBytes, 0, 0) == newCapacityBytes) {
      impl_.z_ += newCap - oldCap;
    } else {
      T* newB; // intentionally uninitialized
      try {
        newB = M_allocate(newCap);
        try {
          M_relocate(newB);
        } catch (...) {
          M_deallocate(newB, newCap);
          return; // swallow the error
        }
      } catch (...) {
        return;
      }
      if (impl_.b_)
        M_deallocate(impl_.b_, impl_.z_ - impl_.b_);
      impl_.z_ = newB + newCap;
      impl_.e_ = newB + (impl_.e_ - impl_.b_);
      impl_.b_ = newB;
    }
  }

private:

  bool reserve_in_place(size_type n) {
    if (!usingStdAllocator::value || !usingJEMalloc()) return false;

    // jemalloc can never grow in place blocks smaller than 4096 bytes.
    if ((impl_.z_ - impl_.b_) * sizeof(T) <
      folly::jemallocMinInPlaceExpandable) return false;

    auto const newCapacityBytes = folly::goodMallocSize(n * sizeof(T));
    void* p = impl_.b_;
    if (xallocx(p, newCapacityBytes, 0, 0) == newCapacityBytes) {
      impl_.z_ = impl_.b_ + newCapacityBytes / sizeof(T);
      return true;
    }
    return false;
  }

  //===========================================================================
  //---------------------------------------------------------------------------
  // element access
public:

  reference operator[](size_type n) {
    assert(n < size());
    return impl_.b_[n];
  }
  const_reference operator[](size_type n) const {
    assert(n < size());
    return impl_.b_[n];
  }
  const_reference at(size_type n) const {
    if (UNLIKELY(n >= size())) {
      throw std::out_of_range("fbvector: index is greater than size.");
    }
    return (*this)[n];
  }
  reference at(size_type n) {
    auto const& cThis = *this;
    return const_cast<reference>(cThis.at(n));
  }
  reference front() {
    assert(!empty());
    return *impl_.b_;
  }
  const_reference front() const {
    assert(!empty());
    return *impl_.b_;
  }
  reference back()  {
    assert(!empty());
    return impl_.e_[-1];
  }
  const_reference back() const {
    assert(!empty());
    return impl_.e_[-1];
  }

  //===========================================================================
  //---------------------------------------------------------------------------
  // data access
public:

  T* data() noexcept {
    return impl_.b_;
  }
  const T* data() const noexcept {
    return impl_.b_;
  }

  //===========================================================================
  //---------------------------------------------------------------------------
  // modifiers (common)
public:

  template <class... Args>
  void emplace_back(Args&&... args)  {
    if (impl_.e_ != impl_.z_) {
      M_construct(impl_.e_, std::forward<Args>(args)...);
      ++impl_.e_;
    } else {
      emplace_back_aux(std::forward<Args>(args)...);
    }
  }

  void
  push_back(const T& value) {
    if (impl_.e_ != impl_.z_) {
      M_construct(impl_.e_, value);
      ++impl_.e_;
    } else {
      emplace_back_aux(value);
    }
  }

  void
  push_back(T&& value) {
    if (impl_.e_ != impl_.z_) {
      M_construct(impl_.e_, std::move(value));
      ++impl_.e_;
    } else {
      emplace_back_aux(std::move(value));
    }
  }

  void pop_back() {
    assert(!empty());
    --impl_.e_;
    M_destroy(impl_.e_);
  }

  void swap(fbvector& other) noexcept {
    if (!usingStdAllocator::value &&
        A::propagate_on_container_swap::value)
      swap(impl_, other.impl_);
    else impl_.swapData(other.impl_);
  }

  void clear() noexcept {
    M_destroy_range_e(impl_.b_);
  }

private:

  // std::vector implements a similar function with a different growth
  //  strategy: empty() ? 1 : capacity() * 2.
  //
  // fbvector grows differently on two counts:
  //
  // (1) initial size
  //     Instead of grwoing to size 1 from empty, and fbvector allocates at
  //     least 64 bytes. You may still use reserve to reserve a lesser amount
  //     of memory.
  // (2) 1.5x
  //     For medium-sized vectors, the growth strategy is 1.5x. See the docs
  //     for details.
  //     This does not apply to very small or very large fbvectors. This is a
  //     heuristic.
  //     A nice addition to fbvector would be the capability of having a user-
  //     defined growth strategy, probably as part of the allocator.
  //

  size_type computePushBackCapacity() const {
    if (capacity() == 0) {
      return std::max(64 / sizeof(T), size_type(1));
    }
    if (capacity() < folly::jemallocMinInPlaceExpandable / sizeof(T)) {
      return capacity() * 2;
    }
    if (capacity() > 4096 * 32 / sizeof(T)) {
      return capacity() * 2;
    }
    return (capacity() * 3 + 1) / 2;
  }

  template <class... Args>
  void emplace_back_aux(Args&&... args);

  //===========================================================================
  //---------------------------------------------------------------------------
  // modifiers (erase)
public:

  iterator erase(const_iterator position) {
    return erase(position, position + 1);
  }

  iterator erase(const_iterator first, const_iterator last) {
    assert(isValid(first) && isValid(last));
    assert(first <= last);
    if (first != last) {
      if (last == end()) {
        M_destroy_range_e((iterator)first);
      } else {
        if (folly::IsRelocatable<T>::value && usingStdAllocator::value) {
          D_destroy_range_a((iterator)first, (iterator)last);
          if (last - first >= cend() - last) {
            std::memcpy((void*)first, (void*)last, (cend() - last) * sizeof(T));
          } else {
            std::memmove((iterator)first, last, (cend() - last) * sizeof(T));
          }
          impl_.e_ -= (last - first);
        } else {
          std::copy(std::make_move_iterator((iterator)last),
                    std::make_move_iterator(end()), (iterator)first);
          auto newEnd = impl_.e_ - std::distance(first, last);
          M_destroy_range_e(newEnd);
        }
      }
    }
    return (iterator)first;
  }

  //===========================================================================
  //---------------------------------------------------------------------------
  // modifiers (insert)
private: // we have the private section first because it defines some macros

  bool isValid(const_iterator it) {
    return cbegin() <= it && it <= cend();
  }

  size_type computeInsertCapacity(size_type n) {
    size_type nc = std::max(computePushBackCapacity(), size() + n);
    size_type ac = folly::goodMallocSize(nc * sizeof(T)) / sizeof(T);
    return ac;
  }

  //---------------------------------------------------------------------------
  //
  // make_window takes an fbvector, and creates an uninitialized gap (a
  //  window) at the given position, of the given size. The fbvector must
  //  have enough capacity.
  //
  // Explanation by picture.
  //
  //    123456789______
  //        ^
  //        make_window here of size 3
  //
  //    1234___56789___
  //
  // If something goes wrong and the window must be destroyed, use
  //  undo_window to provide a weak exception guarantee. It destroys
  //  the right ledge.
  //
  //    1234___________
  //
  //---------------------------------------------------------------------------
  //
  // wrap_frame takes an inverse window and relocates an fbvector around it.
  //  The fbvector must have at least as many elements as the left ledge.
  //
  // Explanation by picture.
  //
  //        START
  //    fbvector:             inverse window:
  //    123456789______       _____abcde_______
  //                          [idx][ n ]
  //
  //        RESULT
  //    _______________       12345abcde6789___
  //
  //---------------------------------------------------------------------------
  //
  // insert_use_fresh_memory returns true iff the fbvector should use a fresh
  //  block of memory for the insertion. If the fbvector does not have enough
  //  spare capacity, then it must return true. Otherwise either true or false
  //  may be returned.
  //
  //---------------------------------------------------------------------------
  //
  // These three functions, make_window, wrap_frame, and
  //  insert_use_fresh_memory, can be combined into a uniform interface.
  // Since that interface involves a lot of case-work, it is built into
  //  some macros: FOLLY_FBVECTOR_INSERT_(START|TRY|END)
  // Macros are used in an attempt to let GCC perform better optimizations,
  //  especially control flow optimization.
  //

  //---------------------------------------------------------------------------
  // window

  void make_window(iterator position, size_type n) {
    assert(isValid(position));
    assert(size() + n <= capacity());
    assert(n != 0);

    // The result is guaranteed to be non-negative, so use an unsigned type:
    size_type tail = std::distance(position, impl_.e_);

    if (tail <= n) {
      relocate_move(position + n, position, impl_.e_);
      relocate_done(position + n, position, impl_.e_);
      impl_.e_ += n;
    } else {
      if (folly::IsRelocatable<T>::value && usingStdAllocator::value) {
        std::memmove(position + n, position, tail * sizeof(T));
        impl_.e_ += n;
      } else {
        D_uninitialized_move_a(impl_.e_, impl_.e_ - n, impl_.e_);
        try {
          std::copy_backward(std::make_move_iterator(position),
                             std::make_move_iterator(impl_.e_ - n), impl_.e_);
        } catch (...) {
          D_destroy_range_a(impl_.e_ - n, impl_.e_ + n);
          impl_.e_ -= n;
          throw;
        }
        impl_.e_ += n;
        D_destroy_range_a(position, position + n);
      }
    }
  }

  void undo_window(iterator position, size_type n) noexcept {
    D_destroy_range_a(position + n, impl_.e_);
    impl_.e_ = position;
  }

  //---------------------------------------------------------------------------
  // frame

  void wrap_frame(T* ledge, size_type idx, size_type n) {
    assert(size() >= idx);
    assert(n != 0);

    relocate_move(ledge, impl_.b_, impl_.b_ + idx);
    try {
      relocate_move(ledge + idx + n, impl_.b_ + idx, impl_.e_);
    } catch (...) {
      relocate_undo(ledge, impl_.b_, impl_.b_ + idx);
      throw;
    }
    relocate_done(ledge, impl_.b_, impl_.b_ + idx);
    relocate_done(ledge + idx + n, impl_.b_ + idx, impl_.e_);
  }

  //---------------------------------------------------------------------------
  // use fresh?

  bool insert_use_fresh(const_iterator cposition, size_type n) {
    if (cposition == cend()) {
      if (size() + n <= capacity()) return false;
      if (reserve_in_place(size() + n)) return false;
      return true;
    }

    if (size() + n > capacity()) return true;

    return false;
  }

  //---------------------------------------------------------------------------
  // interface

  #define FOLLY_FBVECTOR_INSERT_START(cpos, n)                                \
    assert(isValid(cpos));                                                    \
    T* position = const_cast<T*>(cpos);                                       \
    size_type idx = std::distance(impl_.b_, position);                        \
    bool fresh = insert_use_fresh(position, n);                               \
    T* b;                                                                     \
    size_type newCap = 0;                                                     \
                                                                              \
    if (fresh) {                                                              \
      newCap = computeInsertCapacity(n);                                      \
      b = M_allocate(newCap);                                                 \
    } else {                                                                  \
      make_window(position, 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 {                                                                \
        undo_window(position, 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;                                                        \
    }                                                                         \

  //---------------------------------------------------------------------------
  // insert functions
public:

  template <class... Args>
  iterator emplace(const_iterator cpos, Args&&... args) {
    FOLLY_FBVECTOR_INSERT_START(cpos, 1)
      M_construct(start, std::forward<Args>(args)...);
    FOLLY_FBVECTOR_INSERT_TRY(cpos, 1)
      M_destroy(start);
    FOLLY_FBVECTOR_INSERT_END(cpos, 1)
  }

  iterator insert(const_iterator cpos, const T& value) {
    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)
  }

  iterator insert(const_iterator cpos, T&& value) {
    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)
  }

  iterator insert(const_iterator cpos, size_type n, VT value) {
    if (n == 0) return (iterator)cpos;
    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)
  }

  template <class It, class Category = typename
            std::iterator_traits<It>::iterator_category>
  iterator insert(const_iterator cpos, It first, It last) {
    return insert(cpos, first, last, Category());
  }

  iterator insert(const_iterator cpos, std::initializer_list<T> il) {
    return insert(cpos, il.begin(), il.end());
  }

  //---------------------------------------------------------------------------
  // insert dispatch for iterator types
private:

  template <class FIt>
  iterator insert(const_iterator cpos, FIt first, FIt last,
                  std::forward_iterator_tag) {
    size_type n = std::distance(first, last);
    if (n == 0) return (iterator)cpos;

    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)
  }

  template <class IIt>
  iterator insert(const_iterator cpos, IIt first, IIt last,
                  std::input_iterator_tag) {
    T* position = const_cast<T*>(cpos);
    assert(isValid(position));
    size_type idx = std::distance(begin(), position);

    fbvector storage(std::make_move_iterator(position),
                     std::make_move_iterator(end()),
                     A::select_on_container_copy_construction(impl_));
    M_destroy_range_e(position);
    for (; first != last; ++first) emplace_back(*first);
    insert(cend(), std::make_move_iterator(storage.begin()),
           std::make_move_iterator(storage.end()));
    return impl_.b_ + idx;
  }

  //===========================================================================
  //---------------------------------------------------------------------------
  // lexicographical functions (others from boost::totally_ordered superclass)
public:

  bool operator==(const fbvector& other) const {
    return size() == other.size() && std::equal(begin(), end(), other.begin());
  }

  bool operator<(const fbvector& other) const {
    return std::lexicographical_compare(
      begin(), end(), other.begin(), other.end());
  }

  //===========================================================================
  //---------------------------------------------------------------------------
  // friends
private:

  template <class _T, class _A>
  friend _T* relinquish(fbvector<_T, _A>&);

  template <class _T, class _A>
  friend void attach(fbvector<_T, _A>&, _T* data, size_t sz, size_t cap);

}; // class fbvector


//=============================================================================
//-----------------------------------------------------------------------------
// outlined functions (gcc, you finicky compiler you)

template <typename T, typename Allocator>
template <class... Args>
void fbvector<T, Allocator>::emplace_back_aux(Args&&... args) {
  size_type byte_sz = folly::goodMallocSize(
    computePushBackCapacity() * sizeof(T));
  if (usingStdAllocator::value
      && usingJEMalloc()
      && ((impl_.z_ - impl_.b_) * sizeof(T) >=
          folly::jemallocMinInPlaceExpandable)) {
    // Try to reserve in place.
    // Ask xallocx to allocate in place at least size()+1 and at most sz space.
    // xallocx will allocate as much as possible within that range, which
    //  is the best possible outcome: if sz space is available, take it all,
    //  otherwise take as much as possible. If nothing is available, then fail.
    // In this fashion, we never relocate if there is a possibility of
    //  expanding in place, and we never reallocate by less than the desired
    //  amount unless we cannot expand further. Hence we will not reallocate
    //  sub-optimally twice in a row (modulo the blocking memory being freed).
    size_type lower = folly::goodMallocSize(sizeof(T) + size() * sizeof(T));
    size_type upper = byte_sz;
    size_type extra = upper - lower;

    void* p = impl_.b_;
    size_t actual;

    if ((actual = xallocx(p, lower, extra, 0)) >= lower) {
      impl_.z_ = impl_.b_ + actual / sizeof(T);
      M_construct(impl_.e_, std::forward<Args>(args)...);
      ++impl_.e_;
      return;
    }
  }

  // Reallocation failed. Perform a manual relocation.
  size_type sz = byte_sz / sizeof(T);
  auto newB = M_allocate(sz);
  auto newE = newB + size();
  try {
    if (folly::IsRelocatable<T>::value && usingStdAllocator::value) {
      // For linear memory access, relocate before construction.
      // By the test condition, relocate is noexcept.
      // Note that there is no cleanup to do if M_construct throws - that's
      //  one of the beauties of relocation.
      // Benchmarks for this code have high variance, and seem to be close.
      relocate_move(newB, impl_.b_, impl_.e_);
      M_construct(newE, std::forward<Args>(args)...);
      ++newE;
    } else {
      M_construct(newE, std::forward<Args>(args)...);
      ++newE;
      try {
        M_relocate(newB);
      } catch (...) {
        M_destroy(newE - 1);
        throw;
      }
    }
  } catch (...) {
    M_deallocate(newB, sz);
    throw;
  }
  if (impl_.b_) M_deallocate(impl_.b_, size());
  impl_.b_ = newB;
  impl_.e_ = newE;
  impl_.z_ = newB + sz;
}

//=============================================================================
//-----------------------------------------------------------------------------
// specialized functions

template <class T, class A>
void swap(fbvector<T, A>& lhs, fbvector<T, A>& rhs) noexcept {
  lhs.swap(rhs);
}

//=============================================================================
//-----------------------------------------------------------------------------
// other

namespace detail {

// Format support.
template <class T, class A>
struct IndexableTraits<fbvector<T, A>>
  : public IndexableTraitsSeq<fbvector<T, A>> {
};

}  // namespace detail

template <class T, class A>
void compactResize(fbvector<T, A>* v, size_t sz) {
  v->resize(sz);
  v->shrink_to_fit();
}

// DANGER
//
// relinquish and attach are not a members function specifically so that it is
//  awkward to call them. It is very easy to shoot yourself in the foot with
//  these functions.
//
// If you call relinquish, then it is your responsibility to free the data
//  and the storage, both of which may have been generated in a non-standard
//  way through the fbvector's allocator.
//
// If you call attach, it is your responsibility to ensure that the fbvector
//  is fresh (size and capacity both zero), and that the supplied data is
//  capable of being manipulated by the allocator.
// It is acceptable to supply a stack pointer IF:
//  (1) The vector's data does not outlive the stack pointer. This includes
//      extension of the data's life through a move operation.
//  (2) The pointer has enough capacity that the vector will never be
//      relocated.
//  (3) Insert is not called on the vector; these functions have leeway to
//      relocate the vector even if there is enough capacity.
//  (4) A stack pointer is compatible with the fbvector's allocator.
//

template <class T, class A>
T* relinquish(fbvector<T, A>& v) {
  T* ret = v.data();
  v.impl_.b_ = v.impl_.e_ = v.impl_.z_ = nullptr;
  return ret;
}

template <class T, class A>
void attach(fbvector<T, A>& v, T* data, size_t sz, size_t cap) {
  assert(v.data() == nullptr);
  v.impl_.b_ = data;
  v.impl_.e_ = data + sz;
  v.impl_.z_ = data + cap;
}

} // namespace folly

#endif // FOLLY_FBVECTOR_H
