New project structure to satisfy Modular Boost requirements.

This commit is contained in:
Antony Polukhin
2014-01-11 19:02:05 +04:00
parent 5977f9ce6e
commit 5f97225a18
24 changed files with 0 additions and 377 deletions

37
doc/Jamfile.v2 Normal file
View File

@@ -0,0 +1,37 @@
# Copyright Antony Polukhin 2011-2013.
# Use, modification, and distribution are
# subject to 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)
using quickbook ;
import boostbook : boostbook ;
import doxygen ;
doxygen autodoc
:
[ glob ../../../boost/type_index.hpp ]
[ glob ../../../boost/type_index/*.hpp ]
:
<doxygen:param>EXTRACT_ALL=NO
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>"PREDEFINED=\"stl_type_info=std::type_info\" \\
\"BOOST_TYPE_INDEX_DOXYGEN_INVOKED\" \\
\"detail::stl_type_info=std::type_info\""
<xsl:param>"boost.doxygen.reftitle=Boost.TypeIndex Header Reference"
;
xml type_index : type_index.qbk ;
boostbook standalone
:
type_index
:
<xsl:param>boost.root=http://www.boost.org/doc/libs/1_53_0
# <xsl:param>boost.root=../../../..
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
<dependency>autodoc
;

273
doc/type_index.qbk Normal file
View File

@@ -0,0 +1,273 @@
[library Boost.TypeIndex
[quickbook 1.6]
[version 2.1]
[copyright 2012-2013 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 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 of Standard Library currently 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 library was designed to work around all those issues.
[note `T` means type here. Think of it as of `T` in `template <class T>` ]
[warning During the Boost review was decided, that it is better to use interface close to v1.0 of this library. Version 3.0 will attempt to fix all the issues found during the review. ]
[endsect]
[section Getting started]
`boost::type_info` is a drop-in replacement for `std::type_info` and `boost::type_index` is a drop-in
replacement for `std::type_index`. Unlike Standard Library versions those classes may work without RTTI.
`boost::type_index` provides the full set of comparison operators, hashing functions and ostream
operators, so it can be used with any container class.
To start using Boost.TypeIndex:
[table:porting
[[Replace this:][With the following:]]
[[``
#include <typeinfo>
#include <typeindex>
``][``
#include <boost/type_index/type_info.hpp>
#include <boost/type_index/type_index.hpp>
`` or ``
#include <boost/type_index.hpp>
``]]
[[``
std::type_info
std::type_index
``][``
boost::type_info
boost::type_index
``]]
[[``
typeid(T)
typeid(please_save_modifiers<T>)
typeid(T).name() // not human readable
typeid(variable)
``][``
boost::type_id<T>()
boost::type_id_with_cvr<T>()
boost::type_id<T>().name_demangled() // human readable
boost::type_id_rtti_only(variable)
``]]
]
Here is how TypeIndex could be used in `boost/any.hpp`:
[table:any
[[Before] [With TypeIndex]]
[[``#include <typeinfo>``][``#include <boost/type_index/type_info.hpp>``]]
[[``
virtual const std::type_info & type() const BOOST_NOEXCEPT
{
// requires RTTI
return typeid(ValueType);
}
``] [``
virtual const boost::type_info & type() const BOOST_NOEXCEPT
{
// now works even with RTTI disabled
return boost::type_id<ValueType>();
}
``]]
]
Here is how TypeIndex could be used in `boost/variant/variant.hpp`:
[table:variant
[[Before] [With TypeIndex]]
[[``
#if !defined(BOOST_NO_TYPEID)
#include <typeinfo> // for typeid, std::type_info
#endif // BOOST_NO_TYPEID
``][``
#include <boost/type_info/type_info.hpp>
``]]
[[``
#if !defined(BOOST_NO_TYPEID)
class reflect
: public static_visitor<const std::type_info&>
{
public: // visitor interfaces
template <typename T>
const std::type_info& operator()(const T&) const BOOST_NOEXCEPT
{
return typeid(T);
}
};
#endif // BOOST_NO_TYPEID
``][``
class reflect
: public static_visitor<const boost::type_info&>
{
public: // visitor interfaces
template <typename T>
const boost::type_info& operator()(const T&) const BOOST_NOEXCEPT
{
return boost::type_id<T>();
}
};
``]]
[[``
#if !defined(BOOST_NO_TYPEID)
const std::type_info& type() const
{
detail::variant::reflect visitor;
return this->apply_visitor(visitor);
}
#endif
``] [``
const boost::type_info& type() const
{
detail::variant::reflect visitor;
return this->apply_visitor(visitor);
}
``]]
]
[endsect]
[section Examples]
[import ../examples/demangled_names.cpp]
[section Getting human readable and mangled type names] [type_index_names_example] [endsect]
[import ../examples/registry.cpp]
[section Storing information about a type in container ] [type_index_registry_example] [endsect]
[import ../examples/inheritance.cpp]
[section Getting through the inheritance to receive a real type name ] [type_index_derived_example] [endsect]
[import ../examples/exact_types_match.cpp]
[section Exact type match: storing type with const, volatile and reference ] [type_index_exact_type_match_example] [endsect]
[endsect]
[xinclude autodoc.xml]
[section Space and Performance]
* `template_info` uses macro for getting full text representation of function name which could lead to code bloat,
so prefer using `type_info` type.
* `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()` usually require dynamic memory allocation and some computations, so they are not recommended for usage in performance critical sections.
[endsect]
[section Code bloat]
Without RTTI TypeIndex library will switch from using `boost::type_info` class to `boost::template_info`.
`boost::template_info` uses macro for getting full text representation of function name for each type that
is passed to `type_id()` and `type_id_with_cvr()` functions.
This leads to big strings in binary file:
```
static const char* boost::detail::ctti<T>::n() [with T = int]
static const char* boost::detail::ctti<T>::n() [with T = user_defined_type]
```
While using RTTI, you'll get the following (more compact) string in binary file:
```
i
17user_defined_type
```
[endsect]
[section Compiler support]
TypeIndex has been tested and successfully work on MSVC2010, GCC-4.5, Clang-2.9. If your compiler is not
in a list of tested compilers, you must correctly define `BOOST_TYPE_INDEX_FUNCTION_SIGNATURE`,
`BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` macroses:
# define `BOOST_TYPE_INDEX_FUNCTION_SIGNATURE` to a compiler specific macro, that outputs the *whole*
function signature, including template parameters
# define `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` to `0`
# get the output of `boost::template_id<int>().name()`
# set `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` equal to characters count before last occurrence of `int` in output
# set `BOOST_TYPE_INDEX_CTTI_END_SKIP` equal to characters count after last occurrence of `int` in output
# check that `boost::template_id<int>().name_demangled()` returns "int"
# (optional, but highly recomended) [@http://www.boost.org/support/bugs.html create ticket] with
feature request to add your compiler to supported compilers list. Include
`BOOST_TYPE_INDEX_FUNCTION_SIGNATURE`, `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and
`BOOST_TYPE_INDEX_CTTI_END_SKIP` values.
Consider the following example:
With `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` set to `0`,
`boost::template_id<int>().name()` returns "const char *__cdecl boost::detail::ctti<int>::n(void)".
Then you shall set `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` to
`sizeof("const char *__cdecl boost::detail::ctti<") - 1` and `BOOST_TYPE_INDEX_CTTI_END_SKIP`
to `sizeof(">::n(void)") - 1`
[endsect]
[section Mixing sources with RTTI on and RTTI off]
Linking a binary from source files that were compiled with different RTTI flags is not a very good
idea and may lead to a lot of surprises. However if there is a very strong need, TypeIndex library
provides a solution for mixing sources: just define `BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY`
macro. This would lead to usage of `boost::template_index` instead of `boost::type_index` class
and `boost::template_info` instead of `boost::type_info` class.
[note Do not forget to rebuild *all* the projects with `BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY` macro defined ]
You must know that linking RTTI on and RTTI off binaries may succeed even without defining the
`BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY` macro, but that does not mean that you'll get a
working binary. Such actions may break the One Definition Rule. Take a look at the table below,
that shows how the `boost::type_index get_integer();` function will look like with different
RTTI flags:
[table:diffs
[[RTTI on] [RTTI off]]
[[`boost::type_index get_integer();`] [`boost::template_index get_integer();`]]
]
Such differences are usually not detected by linker and lead to errors at runtime.
[warning
Even with `BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY` defined there is no guarantee
that everything will be OK. Libraries that use their own workarounds for disabled RTTI
may fail to link or to work correctly.
]
[endsect]
[section Acknowledgements]
In order of helping and advising:
* Peter Dimov for writing source codes in late 2007, ideas from which were refined and put into this library.
* Agustín Bergé K-ballo for helping with docs and fixing a lot of typos.
* Niall Douglas for generating a lot of great ideas and reviewing the sources.
[endsect]