X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2Fdocs%2FTraits.md;h=daacadbeebcde56fe1cb437417f4878dc0a6ebfe;hb=6ae2206d4a23d683877e33919a469abfdfc411e5;hp=b3761629c31c0efaff63b9ddb40b04ca2604ef4f;hpb=636f38ca19dd9a0ba60787e59e215f3789961e7a;p=folly.git diff --git a/folly/docs/Traits.md b/folly/docs/Traits.md index b3761629..daacadbe 100644 --- a/folly/docs/Traits.md +++ b/folly/docs/Traits.md @@ -1,175 +1,161 @@ - 'folly/Traits.h' - ----------------- +'folly/Traits.h' +----------------- - Implements traits complementary to those provided in +Implements traits complementary to those provided in * Implements `IsRelocatable` trait. * Implements `IsOneOf` trait * Macros to state the assumptions easily - ### Motivation - *** - - 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. - - - ### 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: - - ```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. - - ```Cpp - class NonRelocatableType { - private: - char buffer[1024]; - char * pointerToBuffer; - ... - public: - NonRelocatableType() : pointerToBuffer(buffer) {} - ... - }; - ``` - - We can optimize the task of moving a relocatable type T using memcpy. - IsRelocatable::value describes the ability of moving around memory - a value of type T by using memcpy. - - ### Usage - *** - - * Declaring types - ```Cpp - template - class MyParameterizedType; - - class MySimpleType; - ``` - - * Declaring a type as relocatable - - Appending the lines below after definition of My*Type - (`MyParameterizedType` or `MySimpleType`) will declare it as relocatable - - ```Cpp - /* Definition of My*Type goes here */ - // global namespace (not inside any namespace) - namespace folly { - // defining specialization of IsRelocatable for MySimpleType - template <> - struct IsRelocatable : boost::true_type {}; - // defining specialization of IsRelocatable for MyParameterizedType - template - struct IsRelocatable> - : ::boost::true_type {}; +### Motivation +*** + +`` 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 the Standard. + + +### 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: + +```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. + +```Cpp +class NonRelocatableType { +private: + char buffer[1024]; + char * pointerToBuffer; + ... +public: + NonRelocatableType() : pointerToBuffer(buffer) {} + ... +}; +``` + +We can optimize the task of moving a relocatable type T using memcpy. +IsRelocatable::value describes the ability of moving around memory +a value of type T by using memcpy. + +### Usage +*** + + * Declaring types + + ```Cpp + template + class MyParameterizedType; + + class MySimpleType; + ``` + + * Declaring a type as relocatable + + Appending the lines below after definition of My*Type + (`MyParameterizedType` or `MySimpleType`) will declare it as relocatable + + ```Cpp + /* Definition of My*Type goes here */ + // global namespace (not inside any namespace) + namespace folly { + // defining specialization of IsRelocatable for MySimpleType + template <> + struct IsRelocatable : std::true_type {}; + // defining specialization of IsRelocatable for MyParameterizedType + template + struct IsRelocatable> + : ::std::true_type {}; + } + ``` * To make it easy to state assumptions for a regular type or a family of - parameterized type, various macros can be used as shown below. + parameterized type, various macros can be used as shown below. - * Stating that a type is Relocatable using a macro + * Stating that a type is Relocatable using a macro - ```Cpp - // global namespace - namespace folly { - // For a Regular Type - FOLLY_ASSUME_RELOCATABLE(MySimpleType); - // For a Parameterized Type - FOLLY_ASSUME_RELOCATABLE(MyParameterizedType); - } - ``` + ```Cpp + // global namespace + namespace folly { + // For a Regular Type + FOLLY_ASSUME_RELOCATABLE(MySimpleType); + // For a Parameterized Type + FOLLY_ASSUME_RELOCATABLE(MyParameterizedType); + } + ``` - * Stating that a type has no throw constructor using a macro +`fbvector` only works with relocatable objects. If assumptions are not stated +explicitly, `fbvector` or `fbvector` +will fail to compile due to assertion below: - ```Cpp - namespace boost { - // For a Regular Type - FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR(MySimpleType); - // For a Parameterized Type - FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR(MyParameterizedType); - } - ``` - - `fbvector` only works with relocatable objects. If assumptions are not stated - explicitly, `fbvector` or `fbvector` - will fail to compile due to assertion below: - - ```Cpp - BOOST_STATIC_ASSERT( - IsRelocatable::value - ); - ``` - - 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 - - ```Cpp - // at global level, i.e no namespace - // macro for regular type - FOLLY_ASSUME_FBVECTOR_COMPATIBLE(MySimpleType); - // macro for types having 2 template parameters (MyParameterizedType) - FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(MyParameterizedType); - ``` - - Similary, - * 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 - *** - - boost::is_same::value can be used to test if types of T1 and T2 are - same. folly::IsOneOf::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. - - if boost::is_integral::value == 1 and boost::is_integral::value == 1 - then folly::IsOneOf::value will return 1 - +```Cpp +static_assert(IsRelocatable::value, ""); +``` + +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 + + ```Cpp + // at global level, i.e no namespace + // macro for regular type + FOLLY_ASSUME_FBVECTOR_COMPATIBLE(MySimpleType); + // macro for types having 2 template parameters (MyParameterizedType) + FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(MyParameterizedType); + ``` + +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`, 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 +*** + +`std::is_same::value` can be used to test if types of T1 and T2 are +same. `folly::IsOneOf::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.