/*
- * 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.
* optimizations for use with relocatable types and jemalloc.
*/
-#ifndef FOLLY_FBVECTOR_H
-#define FOLLY_FBVECTOR_H
+#pragma once
//=============================================================================
// headers
#include <folly/Likely.h>
#include <folly/Malloc.h>
#include <folly/Traits.h>
-
-#include <boost/operators.hpp>
+#include <folly/portability/BitsFunctexcept.h>
//=============================================================================
// forward declaration
namespace folly {
template <class T, class Allocator>
-class fbvector : private boost::totally_ordered<fbvector<T, Allocator>> {
+class fbvector {
//===========================================================================
//---------------------------------------------------------------------------
S_destroy_range_a(*this, b_, e_);
}
- D_deallocate(b_, z_ - b_);
+ D_deallocate(b_, size_type(z_ - b_));
}
}
private:
typedef std::integral_constant<bool,
- boost::has_trivial_copy_constructor<T>::value &&
+ IsTriviallyCopyable<T>::value &&
sizeof(T) <= 16 // don't force large structures to be passed by value
> should_pass_by_value;
typedef typename std::conditional<
void M_destroy(T* p) noexcept {
if (usingStdAllocator::value) {
- if (!boost::has_trivial_destructor<T>::value) p->~T();
+ if (!std::is_trivially_destructible<T>::value)
+ p->~T();
} else {
std::allocator_traits<Allocator>::destroy(impl_, p);
}
// optimized
static void S_destroy_range(T* first, T* last) noexcept {
- if (!boost::has_trivial_destructor<T>::value) {
+ if (!std::is_trivially_destructible<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
// optimized
static void S_uninitialized_fill_n(T* dest, size_type n) {
if (folly::IsZeroInitializable<T>::value) {
- std::memset(dest, 0, sizeof(T) * n);
+ if (LIKELY(n != 0)) {
+ std::memset(dest, 0, sizeof(T) * n);
+ }
} else {
auto b = dest;
auto e = dest + n;
static void
S_uninitialized_copy_bits(T* dest, const T* first, const T* last) {
- std::memcpy((void*)dest, (void*)first, (last - first) * sizeof(T));
+ if (last != first) {
+ std::memcpy((void*)dest, (void*)first, (last - first) * sizeof(T));
+ }
}
static void
std::move_iterator<T*> last) {
T* bFirst = first.base();
T* bLast = last.base();
- std::memcpy((void*)dest, (void*)bFirst, (bLast - bFirst) * sizeof(T));
+ if (bLast != bFirst) {
+ std::memcpy((void*)dest, (void*)bFirst, (bLast - bFirst) * sizeof(T));
+ }
}
template <typename It>
}
void relocate_move_or_memcpy(T* dest, T* first, T* last, std::true_type) {
- std::memcpy((void*)dest, (void*)first, (last - first) * sizeof(T));
+ if (first != nullptr) {
+ std::memcpy((void*)dest, (void*)first, (last - first) * sizeof(T));
+ }
}
void relocate_move_or_memcpy(T* dest, T* first, T* last, std::false_type) {
public:
size_type size() const noexcept {
- return impl_.e_ - impl_.b_;
+ return size_type(impl_.e_ - impl_.b_);
}
size_type max_size() const noexcept {
}
size_type capacity() const noexcept {
- return impl_.z_ - impl_.b_;
+ return size_type(impl_.z_ - impl_.b_);
}
bool empty() const noexcept {
throw;
}
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;
}
const_reference at(size_type n) const {
if (UNLIKELY(n >= size())) {
- throw std::out_of_range("fbvector: index is greater than size.");
+ std::__throw_out_of_range("fbvector: index is greater than size.");
}
return (*this)[n];
}
// 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.
+ // Instead of growing to size 1 from empty, 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.
//===========================================================================
//---------------------------------------------------------------------------
- // lexicographical functions (others from boost::totally_ordered superclass)
+ // lexicographical functions
public:
bool operator==(const fbvector& other) const {
return size() == other.size() && std::equal(begin(), end(), other.begin());
}
+ bool operator!=(const fbvector& other) const {
+ return !(*this == other);
+ }
+
bool operator<(const fbvector& other) const {
return std::lexicographical_compare(
begin(), end(), other.begin(), other.end());
}
+ bool operator>(const fbvector& other) const {
+ return other < *this;
+ }
+
+ bool operator<=(const fbvector& other) const {
+ return !(*this > other);
+ }
+
+ bool operator>=(const fbvector& other) const {
+ return !(*this < other);
+ }
+
//===========================================================================
//---------------------------------------------------------------------------
// friends
}
} // namespace folly
-
-#endif // FOLLY_FBVECTOR_H