Commit 87e1985f authored by Tudor Bosman's avatar Tudor Bosman Committed by Jordan DeLong

fix Traits.md

Test Plan: looked at the generated html in a browser

Reviewed By: andrei.alexandrescu@fb.com

FB internal diff: D642998
parent 785dd995
'folly/Traits.h' 'folly/Traits.h'
----------------- -----------------
Implements traits complementary to those provided in <boost/type_traits.h> Implements traits complementary to those provided in <boost/type_traits.h>
* Implements `IsRelocatable` trait. * Implements `IsRelocatable` trait.
* Implements `IsOneOf` trait * Implements `IsOneOf` trait
* Macros to state the assumptions easily * Macros to state the assumptions easily
### Motivation ### Motivation
*** ***
<boost/type_traits.hpp> is the Boost type-traits library defining a `<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 variety of traits such as `is_integral` or `is_floating_point`. This helps
to gain more information about a given type. to gain more information about a given type.
Many traits introduced by Boost have been standardized in C++11. Many traits introduced by Boost have been standardized in C++11.
folly/Traits.h implements traits complementing those present in boost. `folly/Traits.h` implements traits complementing those present in boost.
### IsRelocatable ### IsRelocatable
*** ***
In C++, the default way to move an object is by In C++, the default way to move an object is by
calling the copy constructor and destroying the old copy calling the copy constructor and destroying the old copy
instead of directly copying the memory contents by using memcpy(). instead of directly copying the memory contents by using memcpy().
The conservative approach of moving an object assumes that the copied The conservative approach of moving an object assumes that the copied
object is not relocatable. object is not relocatable.
The two following code sequences should be semantically equivalent for a The two following code sequences should be semantically equivalent for a
relocatable type: relocatable type:
```Cpp ```Cpp
{ {
void conservativeMove(T * from, T * to) { void conservativeMove(T * from, T * to) {
new(to) T(from); new(to) T(from);
(*from).~T(); (*from).~T();
} }
} }
{ {
void optimizedMove(T * from, T * to) { void optimizedMove(T * from, T * to) {
memcpy(to, from, sizeof(T)); memcpy(to, from, sizeof(T));
} }
} }
``` ```
Very few C++ types are non-relocatable. Very few C++ types are non-relocatable.
The type defined below maintains a pointer inside an embedded buffer and The type defined below maintains a pointer inside an embedded buffer and
hence would be non-relocatable. Moving the object by simply copying its hence would be non-relocatable. Moving the object by simply copying its
memory contents would leave the internal pointer pointing to the old buffer. memory contents would leave the internal pointer pointing to the old buffer.
```Cpp ```Cpp
class NonRelocatableType { class NonRelocatableType {
private: private:
char buffer[1024]; char buffer[1024];
char * pointerToBuffer; char * pointerToBuffer;
... ...
public: public:
NonRelocatableType() : pointerToBuffer(buffer) {} NonRelocatableType() : pointerToBuffer(buffer) {}
... ...
}; };
``` ```
We can optimize the task of moving a relocatable type T using memcpy. We can optimize the task of moving a relocatable type T using memcpy.
IsRelocatable<T>::value describes the ability of moving around memory IsRelocatable<T>::value describes the ability of moving around memory
a value of type T by using memcpy. a value of type T by using memcpy.
### Usage ### Usage
*** ***
* Declaring types * Declaring types
```Cpp ```Cpp
template <class T1, class T2> template <class T1, class T2>
class MyParameterizedType; class MyParameterizedType;
...@@ -121,18 +122,18 @@ ...@@ -121,18 +122,18 @@
} }
``` ```
`fbvector` only works with relocatable objects. If assumptions are not stated `fbvector` only works with relocatable objects. If assumptions are not stated
explicitly, `fbvector<MySimpleType>` or `fbvector<MyParameterizedType>` explicitly, `fbvector<MySimpleType>` or `fbvector<MyParameterizedType>`
will fail to compile due to assertion below: will fail to compile due to assertion below:
```Cpp ```Cpp
BOOST_STATIC_ASSERT( BOOST_STATIC_ASSERT(
IsRelocatable<My*Type>::value IsRelocatable<My*Type>::value
); );
``` ```
FOLLY_ASSUME_FBVECTOR_COMPATIBLE*(type) macros can be used to state that type FOLLY_ASSUME_FBVECTOR_COMPATIBLE*(type) macros can be used to state that type
is relocatable and has nothrow constructor. is relocatable and has nothrow constructor.
* Stating that a type is `fbvector-compatible` using macros * Stating that a type is `fbvector-compatible` using macros
i.e. relocatable and has nothrow default constructor i.e. relocatable and has nothrow default constructor
...@@ -145,31 +146,30 @@ ...@@ -145,31 +146,30 @@
FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(MyParameterizedType); FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(MyParameterizedType);
``` ```
Similary, Similarly,
* FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(MyTypeHavingOneParameter) macro is * FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(MyTypeHavingOneParameter) macro is
for family of parameterized types having 1 parameter for family of parameterized types having 1 parameter
* FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3(MyTypeHavingThreeParameters) macro is * FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3(MyTypeHavingThreeParameters) macro is
for family of parameterized types having 3 parameters for family of parameterized types having 3 parameters
* FOLLY_ASSUME_FBVECTOR_COMPATIBLE_4(MyTypeHavingFourParameters) macro is * FOLLY_ASSUME_FBVECTOR_COMPATIBLE_4(MyTypeHavingFourParameters) macro is
for family of parameterized types having 4 parameters for family of parameterized types having 4 parameters
* Few common types, namely `std::basic_string`, `std::vector`, `std::list`, Few common types, namely `std::basic_string`, `std::vector`, `std::list`,
`std::map`, `std::deque`, `std::set`, `std::unique_ptr`, `std::shared_ptr`, `std::map`, `std::deque`, `std::set`, `std::unique_ptr`, `std::shared_ptr`,
`std::function`, `boost::shared_ptr` which are compatible with `fbvector` `std::function`, `boost::shared_ptr` which are compatible with `fbvector` are
are already instantiated and declared compatible with `fbvector`. already instantiated and declared compatible with `fbvector`. `fbvector` can be
`fbvector` can be directly used with any of these C++ types. 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.
### IsOneOf
***
boost::is_same<T1, T2>::value can be used to test if types of T1 and T2 are `std::pair` can be safely assumed to be compatible with `fbvector` if both of
same. folly::IsOneOf<T, T1, Ts...>::value can be used to test if type of T1 its components are.
matches the type of one of the other template parameter, T1, T2, ...Tn.
Recursion is used to implement this type trait.
if boost::is_integral<T>::value == 1 and boost::is_integral<T2>::value == 1 ### IsOneOf
then folly::IsOneOf<T, T1, T2, T3>::value will return 1 ***
`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
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