Commit 03a4c5bd authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Drop the boost dependency from Traits.h and FBVector.h

Summary:
[Folly] Drop the `boost` dependency from `Traits.h` and `FBVector.h`.

Should not need it anymore with the currently supported compilers.

Reviewed By: ericniebler

Differential Revision: D4375572

fbshipit-source-id: df890c07f49b0499d2d2d08aa21c226b2893281e
parent 1807488d
......@@ -210,7 +210,7 @@ public:
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<
......@@ -322,7 +322,8 @@ private:
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);
}
......@@ -360,7 +361,7 @@ private:
// 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
......
......@@ -86,7 +86,7 @@ template <typename> class MPMCQueueBase;
/// use noexcept, you will have to wrap it in something that provides
/// the guarantee. We provide an alternate safe implementation for types
/// that don't use noexcept but that are marked folly::IsRelocatable
/// and boost::has_nothrow_constructor, which is common for folly types.
/// and std::is_nothrow_constructible, which is common for folly types.
/// In particular, if you can declare FOLLY_ASSUME_FBVECTOR_COMPATIBLE
/// then your type can be put in MPMCQueue.
///
......@@ -1310,15 +1310,17 @@ struct SingleElementQueue {
/// enqueue using move construction, either real (if
/// is_nothrow_move_constructible) or simulated using relocation and
/// default construction (if IsRelocatable and has_nothrow_constructor)
template <typename = typename std::enable_if<
(folly::IsRelocatable<T>::value &&
boost::has_nothrow_constructor<T>::value) ||
std::is_nothrow_constructible<T, T&&>::value>::type>
void enqueue(const uint32_t turn,
Atom<uint32_t>& spinCutoff,
const bool updateSpinCutoff,
T&& goner) noexcept {
/// default construction (if IsRelocatable and is_nothrow_constructible)
template <
typename = typename std::enable_if<
(folly::IsRelocatable<T>::value &&
std::is_nothrow_constructible<T>::value) ||
std::is_nothrow_constructible<T, T&&>::value>::type>
void enqueue(
const uint32_t turn,
Atom<uint32_t>& spinCutoff,
const bool updateSpinCutoff,
T&& goner) noexcept {
enqueueImpl(
turn,
spinCutoff,
......
......@@ -8,7 +8,6 @@ ACLOCAL_AMFLAGS = -I m4
CLEANFILES =
noinst_PROGRAMS = generate_fingerprint_tables
generate_fingerprint_tables_SOURCES = build/GenerateFingerprintTables.cpp
generate_fingerprint_tables_LDADD = libfollybase.la
......
......@@ -646,12 +646,4 @@ using UTF8StringPiece = UTF8Range<const char*>;
} // namespace folly
// Hook into boost's type traits
namespace boost {
template <class T>
struct has_nothrow_constructor<folly::basic_fbstring<T> > : true_type {
enum { value = true };
};
} // namespace boost
#include <folly/String-inl.h>
......@@ -36,8 +36,6 @@
#include <bits/c++config.h>
#endif
#include <boost/type_traits.hpp>
#define FOLLY_CREATE_HAS_MEMBER_TYPE_TRAITS(classname, type_name) \
template <typename TTheClass_> \
struct classname##__folly_traits_impl__ { \
......@@ -341,29 +339,12 @@ using StrictConjunction =
struct IsRelocatable< __VA_ARGS__ > : std::true_type {};
/**
* Use this macro ONLY inside namespace boost. When using it with a
* regular type, use it like this:
*
* // Make sure you're at namespace ::boost scope
* template<> FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR(MyType)
*
* When using it with a template type, use it like this:
*
* // Make sure you're at namespace ::boost scope
* template<class T1, class T2>
* FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR(MyType<T1, T2>)
*/
#define FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR(...) \
struct has_nothrow_constructor< __VA_ARGS__ > : ::boost::true_type {};
/**
* The FOLLY_ASSUME_FBVECTOR_COMPATIBLE* macros below encode two
* assumptions: first, that the type is relocatable per IsRelocatable
* above, and that it has a nothrow constructor. Most types can be
* assumed to satisfy both conditions, but it is the responsibility of
* the user to state that assumption. User-defined classes will not
* work with fbvector (see FBVector.h) unless they state this
* combination of properties.
* The FOLLY_ASSUME_FBVECTOR_COMPATIBLE* macros below encode the
* assumption that the type is relocatable per IsRelocatable
* above. Many types can be assumed to satisfy this condition, but
* it is the responsibility of the user to state that assumption.
* User-defined classes will not be optimized for use with
* fbvector (see FBVector.h) unless they state that assumption.
*
* Use FOLLY_ASSUME_FBVECTOR_COMPATIBLE with regular types like this:
*
......@@ -382,40 +363,35 @@ using StrictConjunction =
*/
// Use this macro ONLY at global level (no namespace)
#define FOLLY_ASSUME_FBVECTOR_COMPATIBLE(...) \
namespace folly { template<> FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__) } \
namespace boost { \
template<> FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR(__VA_ARGS__) }
#define FOLLY_ASSUME_FBVECTOR_COMPATIBLE(...) \
namespace folly { \
template <> \
FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__) \
}
// Use this macro ONLY at global level (no namespace)
#define FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(...) \
namespace folly { \
template <class T1> FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__<T1>) } \
namespace boost { \
template <class T1> FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR(__VA_ARGS__<T1>) }
#define FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(...) \
namespace folly { \
template <class T1> \
FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__<T1>) \
}
// Use this macro ONLY at global level (no namespace)
#define FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(...) \
namespace folly { \
template <class T1, class T2> \
FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__<T1, T2>) } \
namespace boost { \
template <class T1, class T2> \
FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR(__VA_ARGS__<T1, T2>) }
#define FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(...) \
namespace folly { \
template <class T1, class T2> \
FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__<T1, T2>) \
}
// Use this macro ONLY at global level (no namespace)
#define FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3(...) \
namespace folly { \
template <class T1, class T2, class T3> \
FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__<T1, T2, T3>) } \
namespace boost { \
template <class T1, class T2, class T3> \
FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR(__VA_ARGS__<T1, T2, T3>) }
#define FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3(...) \
namespace folly { \
template <class T1, class T2, class T3> \
FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__<T1, T2, T3>) \
}
// Use this macro ONLY at global level (no namespace)
#define FOLLY_ASSUME_FBVECTOR_COMPATIBLE_4(...) \
namespace folly { \
template <class T1, class T2, class T3, class T4> \
FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__<T1, T2, T3, T4>) } \
namespace boost { \
template <class T1, class T2, class T3, class T4> \
FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR(__VA_ARGS__<T1, T2, T3, T4>) }
#define FOLLY_ASSUME_FBVECTOR_COMPATIBLE_4(...) \
namespace folly { \
template <class T1, class T2, class T3, class T4> \
FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__<T1, T2, T3, T4>) \
}
/**
* Instantiate FOLLY_ASSUME_FBVECTOR_COMPATIBLE for a few types. It is
......@@ -454,18 +430,6 @@ template <class T>
FOLLY_NAMESPACE_STD_END
namespace boost {
template <class T> class shared_ptr;
template <class T, class U>
struct has_nothrow_constructor< std::pair<T, U> >
: std::integral_constant<bool,
has_nothrow_constructor<T>::value &&
has_nothrow_constructor<U>::value> {};
} // namespace boost
namespace folly {
// STL commonly-used types
......@@ -681,9 +645,6 @@ FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::deque)
FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::unique_ptr)
FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(std::shared_ptr)
FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(std::function)
// Boost
FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(boost::shared_ptr)
#endif
/* Some combinations of compilers and C++ libraries make __int128 and
......
......@@ -189,33 +189,6 @@ after `Widget`'s definition and write this:
If you don't do this, `fbvector<Widget>` will fail to compile
with a `static_assert`.
#### Additional Constraints
Similar improvements are possible in presence of a "simple" type
- more specifically, one that has a trivial assignment (i.e.
assignment is the same as bitblitting the bits over) or a nothrow
default constructor. These traits are used gainfully by
`fbvector` in a variety of places. Fortunately, these traits are
already present in the C++ standard (well, currently in Boost).
To summarize, in order to work with `fbvector`, a type `Widget`
must pass:
static_assert(
IsRelocatable<Widget>::value &&
(boost::has_trivial_assign<T>::value ||
boost::has_nothrow_constructor<T>::value),
"");
These traits go hand in hand; for example, it would be very
difficult to design a class that satisfies one branch of the
conjunction above but not the other. `fbvector` uses these simple
constraints to minimize the number of copies made on many common
operations such as `push_back`, `insert`, or `resize`.
To make it easy for you to state assumptions about a given type
or family of parameterized types, check Traits.h and in
particular handy family of macros FOLLY_ASSUME_FBVECTOR_COMPATIBLE*.
### Miscellaneous
***
......
'folly/Traits.h'
-----------------
Implements traits complementary to those provided in <boost/type_traits.h>
Implements traits complementary to those provided in <type_traits>
* Implements `IsRelocatable` trait.
* Implements `IsOneOf` trait
......@@ -10,12 +10,11 @@ Implements traits complementary to those provided in <boost/type_traits.h>
### Motivation
***
`<boost/type_traits.hpp>` is the Boost type-traits library defining a
variety of traits such as `is_integral` or `is_floating_point`. This helps
to gain more information about a given type.
Many traits introduced by Boost have been standardized in C++11.
`<type_traits>` is the Standard type-traits library defining a variety of traits
such as `is_integral` or `is_floating_point`. This helps to gain more
information about a given type.
`folly/Traits.h` implements traits complementing those present in boost.
`folly/Traits.h` implements traits complementing those present in the Standard.
### IsRelocatable
......@@ -88,11 +87,11 @@ a value of type T by using memcpy.
namespace folly {
// defining specialization of IsRelocatable for MySimpleType
template <>
struct IsRelocatable<MySimpleType> : boost::true_type {};
struct IsRelocatable<MySimpleType> : std::true_type {};
// defining specialization of IsRelocatable for MyParameterizedType
template <class T1, class T2>
struct IsRelocatable<MyParameterizedType<T1, T2>>
: ::boost::true_type {};
: ::std::true_type {};
}
```
......@@ -111,17 +110,6 @@ a value of type T by using memcpy.
}
```
* Stating that a type has no throw constructor using a macro
```Cpp
namespace boost {
// For a Regular Type
FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR(MySimpleType);
// For a Parameterized Type
FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR(MyParameterizedType<T1, T2>);
}
```
`fbvector` only works with relocatable objects. If assumptions are not stated
explicitly, `fbvector<MySimpleType>` or `fbvector<MyParameterizedType>`
will fail to compile due to assertion below:
......@@ -157,9 +145,9 @@ Similarly,
Few common types, namely `std::basic_string`, `std::vector`, `std::list`,
`std::map`, `std::deque`, `std::set`, `std::unique_ptr`, `std::shared_ptr`,
`std::function`, `boost::shared_ptr` which are compatible with `fbvector` are
already instantiated and declared compatible with `fbvector`. `fbvector` can be
directly used with any of these C++ types.
`std::function`, which are compatible with `fbvector` are already instantiated
and declared compatible with `fbvector`. `fbvector` can be directly used with
any of these C++ types.
`std::pair` can be safely assumed to be compatible with `fbvector` if both of
its components are.
......@@ -167,7 +155,7 @@ its components are.
### IsOneOf
***
`boost::is_same<T1, T2>::value` can be used to test if types of T1 and T2 are
same. `folly::IsOneOf<T, T1, Ts...>::value` can be used to test if type of T1
`std::is_same<T1, T2>::value` can be used to test if types of T1 and T2 are
same. `folly::IsOneOf<T, T1, Ts...>::value` can be used to test if type of T1
matches the type of one of the other template parameter, T1, T2, ...Tn.
Recursion is used to implement this type trait.
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