diff --git a/libs/type_index/doc/type_index.qbk~ b/libs/type_index/doc/type_index.qbk~ new file mode 100644 index 0000000..8e4afb3 --- /dev/null +++ b/libs/type_index/doc/type_index.qbk~ @@ -0,0 +1,130 @@ +[library Boost.TypeIndex + [quickbook 1.5] + [version 1.0] + [copyright 2012 Antony Polukhin] + [category Language Features Emulation] + [license + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + [@http://www.boost.org/LICENSE_1_0.txt]) + ] +] + +[section Motivation] +Sometimes getting and storing information about a template type at runtime is required. For such cases a construction like `&typeid(T)` or C++11 class `std::type_index` is usually used. And that is the point, where problems start: + +* `typeid(T)` and `std::type_index` require Run Time Type Info (RTTI) +* some implementations of `typeid(T)` strip const, volatile and references from type, while others don't +* some compilers have bugs and do not correctly compare `std::type_info` objects across shared libraries +* only a few implementations already provide `std::type_index` +* no easy way to store type info without stripping const, volatile and references +* no nice and portable way to get human readable type names + +Boost.TypeIndex was designed to work around those issues. + +[note `T` means type here. Think of it as of `T` in `template ` ] + +[warning This library is not accepted to Boost, it is currrently waiting for review. ] + +[endsect] + +[section Getting started] + +In short: +Just replace `typeid(T)`, `&typeid(T)` with `boost::type_id()` and `std::type_index`, `const std::type_info&` with `boost::type_index`. For cases when RTTI is actually required, replace `typeid(variable)` with `boost::type_id_rtti_only(variable)`. That's all, you are now using Boost.TypeIndex. + +To get nice human readable names, use the `name_demangled()` member function: +`` +type_index ti = type_id(); +std::string nice_name = ti.name_demangled(); +... +std::string nice_name_with_const_volatile_ref = template_id_with_cvr().name_demangled(); +`` + +`template_index` and `type_index` provide the full set of comparison operators, hashing functions and ostream operators. Thay can be used with any container class. + +If you need to preserve `const`, `volatile` and references, use `boost::template_index` instead of `boost::type_index`; `boost::template_id_with_cvr()` instead of `boost::type_id()`. + +[endsect] + + +[section Examples] +All code in the examples will work with and without RTTI support. + +Class that allows to register a given type only once. +`` +class types_registry { + unordered_set types_; + +public: + template + void add_type() { + type_index ti = type_id(); + std::cout << "Adding type " << ti << " to registry \n"; + if (!types_.insert(ti).second) + throw std::logic_error("Type " + ti.name_demangled() + " already registered"); + } + + template + bool has_type() const { + return types_.cend() != types_.find(type_id()); + } +}; + +int main () { + types_registry tr; + tr.add_type(); + tr.add_type(); + + std::cout << "Has type int: " << tr.has_type() + << "\nHas type std::string: " << tr.has_type() + << '\n'; + + try { + tr.add_type(); // Will throw + } catch (const std::logic_error& e) { + // Will print "Type int already registered" + std::cout << e.what() << std::endl; + } +} + +`` + +This will output: +`` +Adding type int to registry +Adding type float to registry +Has type int: 1 +Has type std::string: 0 +`` + +Another example, this time checking for exact parameter match. +`my_unary_function` is a class, that stores a function with result type `ResultT` and any input parameter type. In `operator()`, it checks for input parameter match and then executes the stored function: + +`` +template +class my_unary_function { + void* function_ptr_; + template_index exact_param_t_; + ... + + template + ResultT operator()(ParamT& v) { + BOOST_ASSERT(exact_param_t_ == template_id_with_cvr()); + return (static_cast(function_ptr_))(v); + } +}; +`` + +[endsect] + +[xinclude autodoc.xml] + + +[section Performance] + +`type_index` and `template_index` classes hold a single pointer, so they are easy and fast to copy. Calls to `const char* name()` do not require dynamic memory allocation and usually just return a pointer to an array of chars in a read-only section of the binary image. Comparison operators are optimized as much as possible, and will at worst execute a single `std::strcmp`. Calls to `std::string name_demangled()` for `type_index` do usually require dynamic memory allocation and some computations, so they are not recomended for usage in performance critical sections. Calls to `std::string name_demangled()` for `template_index` only require a single `std::strlen` call and are considerably faster than `std::string name_demangled()` for `type_index`. + +`template_index` uses the `BOOST_CURRENT_FUNCTION` macro, which could lead to code bloat. In those cases where preserving `const`, `volatile` and references is not needed prefer using `type_index`. + +[endsect]