Commit 8ef7d7f1 authored by Joe Loser's avatar Joe Loser Committed by Facebook Github Bot

Replace some bool_constant with constexpr bool in FBVector (#1039)

Summary:
- Some constant expressions are wrapped in a type carrying a bool, but
  are only used in value contexts. Remove the type wrapper
  (bool_constant) use and just use `constexpr bool` directly. This makes the
  usages not have to use `::value` everywhere.
Pull Request resolved: https://github.com/facebook/folly/pull/1039

Reviewed By: Orvid

Differential Revision: D14293828

Pulled By: yfeldblum

fbshipit-source-id: 78399e4fb401ab680a4f1ecef63fb4c2a82927c2
parent 0217f5e2
......@@ -117,7 +117,7 @@ class fbvector {
// allocation
// note that 'allocate' and 'deallocate' are inherited from Allocator
T* D_allocate(size_type n) {
if (usingStdAllocator::value) {
if (usingStdAllocator) {
return static_cast<T*>(checkedMalloc(n * sizeof(T)));
} else {
return std::allocator_traits<Allocator>::allocate(*this, n);
......@@ -125,7 +125,7 @@ class fbvector {
}
void D_deallocate(T* p, size_type n) noexcept {
if (usingStdAllocator::value) {
if (usingStdAllocator) {
free(p);
} else {
std::allocator_traits<Allocator>::deallocate(*this, p, n);
......@@ -145,7 +145,7 @@ class fbvector {
// 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) {
if (usingStdAllocator) {
S_destroy_range(b_, e_);
} else {
S_destroy_range_a(*this, b_, e_);
......@@ -189,7 +189,7 @@ class fbvector {
static void swap(Impl& a, Impl& b) {
using std::swap;
if (!usingStdAllocator::value) {
if (!usingStdAllocator) {
swap(static_cast<Allocator&>(a), static_cast<Allocator&>(b));
}
a.swapData(b);
......@@ -213,22 +213,16 @@ class fbvector {
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
private:
typedef bool_constant<
static constexpr bool should_pass_by_value =
is_trivially_copyable<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 bool_constant<std::is_same<Allocator, std::allocator<T>>::value>
usingStdAllocator;
sizeof(T) <= 16; // don't force large structures to be passed by value
typedef typename std::conditional<should_pass_by_value, T, const T&>::type VT;
typedef typename std::conditional<should_pass_by_value, T, T&&>::type MT;
static constexpr bool usingStdAllocator =
std::is_same<Allocator, std::allocator<T>>::value;
typedef bool_constant<
usingStdAllocator::value ||
A::propagate_on_container_move_assignment::value>
usingStdAllocator || A::propagate_on_container_move_assignment::value>
moveIsSwap;
//===========================================================================
......@@ -257,7 +251,7 @@ class fbvector {
template <typename U, typename... Args>
void M_construct(U* p, Args&&... args) {
if (usingStdAllocator::value) {
if (usingStdAllocator) {
new (p) U(std::forward<Args>(args)...);
} else {
std::allocator_traits<Allocator>::construct(
......@@ -282,7 +276,7 @@ class fbvector {
typename U,
typename Enable = typename std::enable_if<std::is_scalar<U>::value>::type>
void M_construct(U* p, U arg) {
if (usingStdAllocator::value) {
if (usingStdAllocator) {
*p = arg;
} else {
std::allocator_traits<Allocator>::construct(impl_, p, arg);
......@@ -309,7 +303,7 @@ class fbvector {
typename Enable =
typename std::enable_if<!std::is_scalar<U>::value>::type>
void M_construct(U* p, const U& value) {
if (usingStdAllocator::value) {
if (usingStdAllocator) {
new (p) U(value);
} else {
std::allocator_traits<Allocator>::construct(impl_, p, value);
......@@ -336,7 +330,7 @@ class fbvector {
// destroy
void M_destroy(T* p) noexcept {
if (usingStdAllocator::value) {
if (usingStdAllocator) {
if (!std::is_trivially_destructible<T>::value) {
p->~T();
}
......@@ -361,7 +355,7 @@ class fbvector {
// 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) {
if (usingStdAllocator) {
S_destroy_range(first, last);
} else {
S_destroy_range_a(impl_, first, last);
......@@ -411,7 +405,7 @@ class fbvector {
// dispatch
void D_uninitialized_fill_n_a(T* dest, size_type sz) {
if (usingStdAllocator::value) {
if (usingStdAllocator) {
S_uninitialized_fill_n(dest, sz);
} else {
S_uninitialized_fill_n_a(impl_, dest, sz);
......@@ -419,7 +413,7 @@ class fbvector {
}
void D_uninitialized_fill_n_a(T* dest, size_type sz, VT value) {
if (usingStdAllocator::value) {
if (usingStdAllocator) {
S_uninitialized_fill_n(dest, sz, value);
} else {
S_uninitialized_fill_n_a(impl_, dest, sz, value);
......@@ -504,7 +498,7 @@ class fbvector {
// dispatch
template <typename It>
void D_uninitialized_copy_a(T* dest, It first, It last) {
if (usingStdAllocator::value) {
if (usingStdAllocator) {
if (folly::is_trivially_copyable<T>::value) {
S_uninitialized_copy_bits(dest, first, last);
} else {
......@@ -654,13 +648,11 @@ class fbvector {
}
// dispatch type trait
typedef bool_constant<
folly::IsRelocatable<T>::value && usingStdAllocator::value>
typedef bool_constant<folly::IsRelocatable<T>::value && usingStdAllocator>
relocate_use_memcpy;
typedef bool_constant<
(std::is_nothrow_move_constructible<T>::value &&
usingStdAllocator::value) ||
(std::is_nothrow_move_constructible<T>::value && usingStdAllocator) ||
!std::is_copy_constructible<T>::value>
relocate_use_move;
......@@ -689,7 +681,7 @@ class fbvector {
// done
void relocate_done(T* /*dest*/, T* first, T* last) noexcept {
if (folly::IsRelocatable<T>::value && usingStdAllocator::value) {
if (folly::IsRelocatable<T>::value && usingStdAllocator) {
// used memcpy; data has been relocated, do not call destructor
} else {
D_destroy_range_a(first, last);
......@@ -698,11 +690,10 @@ class fbvector {
// undo
void relocate_undo(T* dest, T* first, T* last) noexcept {
if (folly::IsRelocatable<T>::value && usingStdAllocator::value) {
if (folly::IsRelocatable<T>::value && usingStdAllocator) {
// used memcpy, old data is still valid, nothing to do
} else if (
std::is_nothrow_move_constructible<T>::value &&
usingStdAllocator::value) {
std::is_nothrow_move_constructible<T>::value && usingStdAllocator) {
// noexcept move everything back, aka relocate_move
relocate_move(first, dest, dest + (last - first));
} else if (!std::is_copy_constructible<T>::value) {
......@@ -769,7 +760,7 @@ class fbvector {
return *this;
}
if (!usingStdAllocator::value &&
if (!usingStdAllocator &&
A::propagate_on_container_copy_assignment::value) {
if (impl_ != other.impl_) {
// can't use other's different allocator to clean up self
......@@ -906,7 +897,7 @@ class fbvector {
// contract dispatch for aliasing under VT optimization
bool dataIsInternalAndNotVT(const T& t) {
if (should_pass_by_value::value) {
if (should_pass_by_value) {
return false;
}
return dataIsInternal(t);
......@@ -1042,7 +1033,7 @@ class fbvector {
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) &&
if ((usingJEMalloc() && usingStdAllocator) &&
newCapacityBytes >= folly::jemallocMinInPlaceExpandable &&
xallocx(p, newCapacityBytes, 0, 0) == newCapacityBytes) {
impl_.z_ += newCap - oldCap;
......@@ -1070,7 +1061,7 @@ class fbvector {
private:
bool reserve_in_place(size_type n) {
if (!usingStdAllocator::value || !usingJEMalloc()) {
if (!usingStdAllocator || !usingJEMalloc()) {
return false;
}
......@@ -1179,7 +1170,7 @@ class fbvector {
}
void swap(fbvector& other) noexcept {
if (!usingStdAllocator::value && A::propagate_on_container_swap::value) {
if (!usingStdAllocator && A::propagate_on_container_swap::value) {
swap(impl_, other.impl_);
} else {
impl_.swapData(other.impl_);
......@@ -1240,7 +1231,7 @@ class fbvector {
if (last == end()) {
M_destroy_range_e((iterator)first);
} else {
if (folly::IsRelocatable<T>::value && usingStdAllocator::value) {
if (folly::IsRelocatable<T>::value && usingStdAllocator) {
D_destroy_range_a((iterator)first, (iterator)last);
if (last - first >= cend() - last) {
std::memcpy((void*)first, (void*)last, (cend() - last) * sizeof(T));
......@@ -1340,7 +1331,7 @@ class fbvector {
relocate_done(position + n, position, impl_.e_);
impl_.e_ += n;
} else {
if (folly::IsRelocatable<T>::value && usingStdAllocator::value) {
if (folly::IsRelocatable<T>::value && usingStdAllocator) {
std::memmove((void*)(position + n), (void*)position, tail * sizeof(T));
impl_.e_ += n;
} else {
......@@ -1628,7 +1619,7 @@ 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() &&
if (usingStdAllocator && usingJEMalloc() &&
((impl_.z_ - impl_.b_) * sizeof(T) >=
folly::jemallocMinInPlaceExpandable)) {
// Try to reserve in place.
......@@ -1660,7 +1651,7 @@ void fbvector<T, Allocator>::emplace_back_aux(Args&&... args) {
auto newB = M_allocate(sz);
auto newE = newB + size();
try {
if (folly::IsRelocatable<T>::value && usingStdAllocator::value) {
if (folly::IsRelocatable<T>::value && usingStdAllocator) {
// 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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment