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 `IsOneOf` trait
* Macros to state the assumptions easily
### Motivation
***
### 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.
`<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.
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
calling the copy constructor and destroying the old copy
instead of directly copying the memory contents by using memcpy().
The conservative approach of moving an object assumes that the copied
object is not relocatable.
The two following code sequences should be semantically equivalent for a
relocatable type:
In C++, the default way to move an object is by
calling the copy constructor and destroying the old copy
instead of directly copying the memory contents by using memcpy().
The conservative approach of moving an object assumes that the copied
object is not relocatable.
The two following code sequences should be semantically equivalent for a
relocatable type:
```Cpp
{
```Cpp
{
void conservativeMove(T * from, T * to) {
new(to) T(from);
(*from).~T();
}
}
}
{
{
void optimizedMove(T * from, T * to) {
memcpy(to, from, sizeof(T));
}
}
```
}
```
Very few C++ types are non-relocatable.
The type defined below maintains a pointer inside an embedded buffer and
hence would be non-relocatable. Moving the object by simply copying its
memory contents would leave the internal pointer pointing to the old buffer.
Very few C++ types are non-relocatable.
The type defined below maintains a pointer inside an embedded buffer and
hence would be non-relocatable. Moving the object by simply copying its
memory contents would leave the internal pointer pointing to the old buffer.
```Cpp
class NonRelocatableType {
private:
```Cpp
class NonRelocatableType {
private:
char buffer[1024];
char * pointerToBuffer;
...
public:
public:
NonRelocatableType() : pointerToBuffer(buffer) {}
...
};
```
};
```
We can optimize the task of moving a relocatable type T using memcpy.
IsRelocatable<T>::value describes the ability of moving around memory
a value of type T by 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
a value of type T by using memcpy.
### Usage
***
### Usage
***
* Declaring types
```Cpp
template <class T1, class T2>
class MyParameterizedType;
......@@ -121,18 +122,18 @@
}
```
`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:
`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:
```Cpp
BOOST_STATIC_ASSERT(
```Cpp
BOOST_STATIC_ASSERT(
IsRelocatable<My*Type>::value
);
```
);
```
FOLLY_ASSUME_FBVECTOR_COMPATIBLE*(type) macros can be used to state that type
is relocatable and has nothrow constructor.
FOLLY_ASSUME_FBVECTOR_COMPATIBLE*(type) macros can be used to state that type
is relocatable and has nothrow constructor.
* Stating that a type is `fbvector-compatible` using macros
i.e. relocatable and has nothrow default constructor
......@@ -145,31 +146,30 @@
FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(MyParameterizedType);
```
Similary,
Similarly,
* FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(MyTypeHavingOneParameter) macro is
for family of parameterized types having 1 parameter
* FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3(MyTypeHavingThreeParameters) macro is
for family of parameterized types having 3 parameters
* FOLLY_ASSUME_FBVECTOR_COMPATIBLE_4(MyTypeHavingFourParameters) macro is
for family of parameterized types having 4 parameters
* 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::pair` can be safely assumed to be compatible with `fbvector` if both
of its components are.
### IsOneOf
***
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.
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.
`std::pair` can be safely assumed to be compatible with `fbvector` if both of
its components are.
if boost::is_integral<T>::value == 1 and boost::is_integral<T2>::value == 1
then folly::IsOneOf<T, T1, T2, T3>::value will return 1
### 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
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