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 { ...@@ -117,7 +117,7 @@ class fbvector {
// allocation // allocation
// note that 'allocate' and 'deallocate' are inherited from Allocator // note that 'allocate' and 'deallocate' are inherited from Allocator
T* D_allocate(size_type n) { T* D_allocate(size_type n) {
if (usingStdAllocator::value) { if (usingStdAllocator) {
return static_cast<T*>(checkedMalloc(n * sizeof(T))); return static_cast<T*>(checkedMalloc(n * sizeof(T)));
} else { } else {
return std::allocator_traits<Allocator>::allocate(*this, n); return std::allocator_traits<Allocator>::allocate(*this, n);
...@@ -125,7 +125,7 @@ class fbvector { ...@@ -125,7 +125,7 @@ class fbvector {
} }
void D_deallocate(T* p, size_type n) noexcept { void D_deallocate(T* p, size_type n) noexcept {
if (usingStdAllocator::value) { if (usingStdAllocator) {
free(p); free(p);
} else { } else {
std::allocator_traits<Allocator>::deallocate(*this, p, n); std::allocator_traits<Allocator>::deallocate(*this, p, n);
...@@ -145,7 +145,7 @@ class fbvector { ...@@ -145,7 +145,7 @@ class fbvector {
// THIS DISPATCH CODE IS DUPLICATED IN fbvector::D_destroy_range_a. // THIS DISPATCH CODE IS DUPLICATED IN fbvector::D_destroy_range_a.
// It has been inlined here for speed. It calls the static fbvector // It has been inlined here for speed. It calls the static fbvector
// methods to perform the actual destruction. // methods to perform the actual destruction.
if (usingStdAllocator::value) { if (usingStdAllocator) {
S_destroy_range(b_, e_); S_destroy_range(b_, e_);
} else { } else {
S_destroy_range_a(*this, b_, e_); S_destroy_range_a(*this, b_, e_);
...@@ -189,7 +189,7 @@ class fbvector { ...@@ -189,7 +189,7 @@ class fbvector {
static void swap(Impl& a, Impl& b) { static void swap(Impl& a, Impl& b) {
using std::swap; using std::swap;
if (!usingStdAllocator::value) { if (!usingStdAllocator) {
swap(static_cast<Allocator&>(a), static_cast<Allocator&>(b)); swap(static_cast<Allocator&>(a), static_cast<Allocator&>(b));
} }
a.swapData(b); a.swapData(b);
...@@ -213,22 +213,16 @@ class fbvector { ...@@ -213,22 +213,16 @@ class fbvector {
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
private: private:
typedef bool_constant< static constexpr bool should_pass_by_value =
is_trivially_copyable<T>::value && is_trivially_copyable<T>::value &&
sizeof(T) <= 16 // don't force large structures to be passed by value 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;
should_pass_by_value; typedef typename std::conditional<should_pass_by_value, T, T&&>::type MT;
typedef
typename std::conditional<should_pass_by_value::value, T, const T&>::type static constexpr bool usingStdAllocator =
VT; std::is_same<Allocator, std::allocator<T>>::value;
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;
typedef bool_constant< typedef bool_constant<
usingStdAllocator::value || usingStdAllocator || A::propagate_on_container_move_assignment::value>
A::propagate_on_container_move_assignment::value>
moveIsSwap; moveIsSwap;
//=========================================================================== //===========================================================================
...@@ -257,7 +251,7 @@ class fbvector { ...@@ -257,7 +251,7 @@ class fbvector {
template <typename U, typename... Args> template <typename U, typename... Args>
void M_construct(U* p, Args&&... args) { void M_construct(U* p, Args&&... args) {
if (usingStdAllocator::value) { if (usingStdAllocator) {
new (p) U(std::forward<Args>(args)...); new (p) U(std::forward<Args>(args)...);
} else { } else {
std::allocator_traits<Allocator>::construct( std::allocator_traits<Allocator>::construct(
...@@ -282,7 +276,7 @@ class fbvector { ...@@ -282,7 +276,7 @@ class fbvector {
typename U, typename U,
typename Enable = typename std::enable_if<std::is_scalar<U>::value>::type> typename Enable = typename std::enable_if<std::is_scalar<U>::value>::type>
void M_construct(U* p, U arg) { void M_construct(U* p, U arg) {
if (usingStdAllocator::value) { if (usingStdAllocator) {
*p = arg; *p = arg;
} else { } else {
std::allocator_traits<Allocator>::construct(impl_, p, arg); std::allocator_traits<Allocator>::construct(impl_, p, arg);
...@@ -309,7 +303,7 @@ class fbvector { ...@@ -309,7 +303,7 @@ class fbvector {
typename Enable = typename Enable =
typename std::enable_if<!std::is_scalar<U>::value>::type> typename std::enable_if<!std::is_scalar<U>::value>::type>
void M_construct(U* p, const U& value) { void M_construct(U* p, const U& value) {
if (usingStdAllocator::value) { if (usingStdAllocator) {
new (p) U(value); new (p) U(value);
} else { } else {
std::allocator_traits<Allocator>::construct(impl_, p, value); std::allocator_traits<Allocator>::construct(impl_, p, value);
...@@ -336,7 +330,7 @@ class fbvector { ...@@ -336,7 +330,7 @@ class fbvector {
// destroy // destroy
void M_destroy(T* p) noexcept { void M_destroy(T* p) noexcept {
if (usingStdAllocator::value) { if (usingStdAllocator) {
if (!std::is_trivially_destructible<T>::value) { if (!std::is_trivially_destructible<T>::value) {
p->~T(); p->~T();
} }
...@@ -361,7 +355,7 @@ class fbvector { ...@@ -361,7 +355,7 @@ class fbvector {
// dispatch // dispatch
// THIS DISPATCH CODE IS DUPLICATED IN IMPL. SEE IMPL FOR DETAILS. // THIS DISPATCH CODE IS DUPLICATED IN IMPL. SEE IMPL FOR DETAILS.
void D_destroy_range_a(T* first, T* last) noexcept { void D_destroy_range_a(T* first, T* last) noexcept {
if (usingStdAllocator::value) { if (usingStdAllocator) {
S_destroy_range(first, last); S_destroy_range(first, last);
} else { } else {
S_destroy_range_a(impl_, first, last); S_destroy_range_a(impl_, first, last);
...@@ -411,7 +405,7 @@ class fbvector { ...@@ -411,7 +405,7 @@ class fbvector {
// dispatch // dispatch
void D_uninitialized_fill_n_a(T* dest, size_type sz) { void D_uninitialized_fill_n_a(T* dest, size_type sz) {
if (usingStdAllocator::value) { if (usingStdAllocator) {
S_uninitialized_fill_n(dest, sz); S_uninitialized_fill_n(dest, sz);
} else { } else {
S_uninitialized_fill_n_a(impl_, dest, sz); S_uninitialized_fill_n_a(impl_, dest, sz);
...@@ -419,7 +413,7 @@ class fbvector { ...@@ -419,7 +413,7 @@ class fbvector {
} }
void D_uninitialized_fill_n_a(T* dest, size_type sz, VT value) { 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); S_uninitialized_fill_n(dest, sz, value);
} else { } else {
S_uninitialized_fill_n_a(impl_, dest, sz, value); S_uninitialized_fill_n_a(impl_, dest, sz, value);
...@@ -504,7 +498,7 @@ class fbvector { ...@@ -504,7 +498,7 @@ class fbvector {
// dispatch // dispatch
template <typename It> template <typename It>
void D_uninitialized_copy_a(T* dest, It first, It last) { void D_uninitialized_copy_a(T* dest, It first, It last) {
if (usingStdAllocator::value) { if (usingStdAllocator) {
if (folly::is_trivially_copyable<T>::value) { if (folly::is_trivially_copyable<T>::value) {
S_uninitialized_copy_bits(dest, first, last); S_uninitialized_copy_bits(dest, first, last);
} else { } else {
...@@ -654,13 +648,11 @@ class fbvector { ...@@ -654,13 +648,11 @@ class fbvector {
} }
// dispatch type trait // dispatch type trait
typedef bool_constant< typedef bool_constant<folly::IsRelocatable<T>::value && usingStdAllocator>
folly::IsRelocatable<T>::value && usingStdAllocator::value>
relocate_use_memcpy; relocate_use_memcpy;
typedef bool_constant< typedef bool_constant<
(std::is_nothrow_move_constructible<T>::value && (std::is_nothrow_move_constructible<T>::value && usingStdAllocator) ||
usingStdAllocator::value) ||
!std::is_copy_constructible<T>::value> !std::is_copy_constructible<T>::value>
relocate_use_move; relocate_use_move;
...@@ -689,7 +681,7 @@ class fbvector { ...@@ -689,7 +681,7 @@ class fbvector {
// done // done
void relocate_done(T* /*dest*/, T* first, T* last) noexcept { 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 // used memcpy; data has been relocated, do not call destructor
} else { } else {
D_destroy_range_a(first, last); D_destroy_range_a(first, last);
...@@ -698,11 +690,10 @@ class fbvector { ...@@ -698,11 +690,10 @@ class fbvector {
// undo // undo
void relocate_undo(T* dest, T* first, T* last) noexcept { 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 // used memcpy, old data is still valid, nothing to do
} else if ( } else if (
std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_constructible<T>::value && usingStdAllocator) {
usingStdAllocator::value) {
// noexcept move everything back, aka relocate_move // noexcept move everything back, aka relocate_move
relocate_move(first, dest, dest + (last - first)); relocate_move(first, dest, dest + (last - first));
} else if (!std::is_copy_constructible<T>::value) { } else if (!std::is_copy_constructible<T>::value) {
...@@ -769,7 +760,7 @@ class fbvector { ...@@ -769,7 +760,7 @@ class fbvector {
return *this; return *this;
} }
if (!usingStdAllocator::value && if (!usingStdAllocator &&
A::propagate_on_container_copy_assignment::value) { A::propagate_on_container_copy_assignment::value) {
if (impl_ != other.impl_) { if (impl_ != other.impl_) {
// can't use other's different allocator to clean up self // can't use other's different allocator to clean up self
...@@ -906,7 +897,7 @@ class fbvector { ...@@ -906,7 +897,7 @@ class fbvector {
// contract dispatch for aliasing under VT optimization // contract dispatch for aliasing under VT optimization
bool dataIsInternalAndNotVT(const T& t) { bool dataIsInternalAndNotVT(const T& t) {
if (should_pass_by_value::value) { if (should_pass_by_value) {
return false; return false;
} }
return dataIsInternal(t); return dataIsInternal(t);
...@@ -1042,7 +1033,7 @@ class fbvector { ...@@ -1042,7 +1033,7 @@ class fbvector {
void* p = impl_.b_; void* p = impl_.b_;
// xallocx() will shrink to precisely newCapacityBytes (which was generated // xallocx() will shrink to precisely newCapacityBytes (which was generated
// by goodMallocSize()) if it successfully shrinks in place. // by goodMallocSize()) if it successfully shrinks in place.
if ((usingJEMalloc() && usingStdAllocator::value) && if ((usingJEMalloc() && usingStdAllocator) &&
newCapacityBytes >= folly::jemallocMinInPlaceExpandable && newCapacityBytes >= folly::jemallocMinInPlaceExpandable &&
xallocx(p, newCapacityBytes, 0, 0) == newCapacityBytes) { xallocx(p, newCapacityBytes, 0, 0) == newCapacityBytes) {
impl_.z_ += newCap - oldCap; impl_.z_ += newCap - oldCap;
...@@ -1070,7 +1061,7 @@ class fbvector { ...@@ -1070,7 +1061,7 @@ class fbvector {
private: private:
bool reserve_in_place(size_type n) { bool reserve_in_place(size_type n) {
if (!usingStdAllocator::value || !usingJEMalloc()) { if (!usingStdAllocator || !usingJEMalloc()) {
return false; return false;
} }
...@@ -1179,7 +1170,7 @@ class fbvector { ...@@ -1179,7 +1170,7 @@ class fbvector {
} }
void swap(fbvector& other) noexcept { 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_); swap(impl_, other.impl_);
} else { } else {
impl_.swapData(other.impl_); impl_.swapData(other.impl_);
...@@ -1240,7 +1231,7 @@ class fbvector { ...@@ -1240,7 +1231,7 @@ class fbvector {
if (last == end()) { if (last == end()) {
M_destroy_range_e((iterator)first); M_destroy_range_e((iterator)first);
} else { } else {
if (folly::IsRelocatable<T>::value && usingStdAllocator::value) { if (folly::IsRelocatable<T>::value && usingStdAllocator) {
D_destroy_range_a((iterator)first, (iterator)last); D_destroy_range_a((iterator)first, (iterator)last);
if (last - first >= cend() - last) { if (last - first >= cend() - last) {
std::memcpy((void*)first, (void*)last, (cend() - last) * sizeof(T)); std::memcpy((void*)first, (void*)last, (cend() - last) * sizeof(T));
...@@ -1340,7 +1331,7 @@ class fbvector { ...@@ -1340,7 +1331,7 @@ class fbvector {
relocate_done(position + n, position, impl_.e_); relocate_done(position + n, position, impl_.e_);
impl_.e_ += n; impl_.e_ += n;
} else { } else {
if (folly::IsRelocatable<T>::value && usingStdAllocator::value) { if (folly::IsRelocatable<T>::value && usingStdAllocator) {
std::memmove((void*)(position + n), (void*)position, tail * sizeof(T)); std::memmove((void*)(position + n), (void*)position, tail * sizeof(T));
impl_.e_ += n; impl_.e_ += n;
} else { } else {
...@@ -1628,7 +1619,7 @@ template <class... Args> ...@@ -1628,7 +1619,7 @@ template <class... Args>
void fbvector<T, Allocator>::emplace_back_aux(Args&&... args) { void fbvector<T, Allocator>::emplace_back_aux(Args&&... args) {
size_type byte_sz = size_type byte_sz =
folly::goodMallocSize(computePushBackCapacity() * sizeof(T)); folly::goodMallocSize(computePushBackCapacity() * sizeof(T));
if (usingStdAllocator::value && usingJEMalloc() && if (usingStdAllocator && usingJEMalloc() &&
((impl_.z_ - impl_.b_) * sizeof(T) >= ((impl_.z_ - impl_.b_) * sizeof(T) >=
folly::jemallocMinInPlaceExpandable)) { folly::jemallocMinInPlaceExpandable)) {
// Try to reserve in place. // Try to reserve in place.
...@@ -1660,7 +1651,7 @@ void fbvector<T, Allocator>::emplace_back_aux(Args&&... args) { ...@@ -1660,7 +1651,7 @@ void fbvector<T, Allocator>::emplace_back_aux(Args&&... args) {
auto newB = M_allocate(sz); auto newB = M_allocate(sz);
auto newE = newB + size(); auto newE = newB + size();
try { try {
if (folly::IsRelocatable<T>::value && usingStdAllocator::value) { if (folly::IsRelocatable<T>::value && usingStdAllocator) {
// For linear memory access, relocate before construction. // For linear memory access, relocate before construction.
// By the test condition, relocate is noexcept. // By the test condition, relocate is noexcept.
// Note that there is no cleanup to do if M_construct throws - that's // 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