New examples

Added a folder with examples. Examples are compiled and run during test
run. Documentation now uses source code of examples in the "Examples"
section
This commit is contained in:
apolukhin
2013-10-14 19:23:18 +04:00
parent 2557b1f8e1
commit 83b8a47c2a
6 changed files with 185 additions and 63 deletions

View File

@@ -49,75 +49,22 @@ If you need to preserve `const`, `volatile` and references, use `boost::template
[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<type_index> types_;
[import ../examples/demangled_names.cpp]
[section Getting human readable and mangled type names] [type_index_names_example] [endsect]
public:
template <class T>
void add_type() {
type_index ti = type_id<T>();
std::cout << "Adding type " << ti << " to registry \n";
if (!types_.insert(ti).second)
throw std::logic_error("Type " + ti.name_demangled() + " already registered");
}
[import ../examples/registry.cpp]
[section Storing information about a type in container ] [type_index_registry_example] [endsect]
template <class T>
bool has_type() const {
return types_.cend() != types_.find(type_id<T>());
}
};
[import ../examples/inheritance.cpp]
[section Getting through the inheritance to receive a real type name ] [type_index_derived_example] [endsect]
int main () {
types_registry tr;
tr.add_type<int>();
tr.add_type<float>();
std::cout << "Has type int: " << tr.has_type<int>()
<< "\nHas type std::string: " << tr.has_type<std::string>()
<< '\n';
try {
tr.add_type<const int>(); // 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 ResultT>
class my_unary_function {
void* function_ptr_;
template_index exact_param_t_;
...
template <class ParamT>
ResultT operator()(ParamT& v) {
BOOST_ASSERT(exact_param_t_ == template_id_with_cvr<ParamT&>());
return (static_cast<ResultT(ParamT&)>(function_ptr_))(v);
}
};
``
[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]

View File

@@ -0,0 +1,42 @@
// Copyright 2013 Antony Polukhin
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt
// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
//[type_index_names_example
//`The following example shows how short (mangled) and human readable type names could be obtained from a type.
// Works with and without RTTI.
#include <boost/type_index/type_index_minimal.hpp>
#include <iostream>
template <class T>
void foo(T) {
std::cout << "\n Short name: " << boost::type_id<T>().name();
std::cout << "\n Readable name: " << boost::type_id<T>().name_demangled();
}
struct user_defined_type{};
int main() {
// Call to
foo(1);
// will output something like this:
//
// Short name: .H
// Readable name: int
user_defined_type t;
foo(t);
// Will output:
//
// Short name: .?AUuser_defined_type@@
// Readable name: struct user_defined_type
}
// The example
//] [/type_index_names_example]

View File

@@ -0,0 +1,56 @@
// Copyright 2013 Antony Polukhin
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt
// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
//[type_index_exact_type_match_example
/*`
The following example shows that `boost::template_index` is able to store the exact type, without stripping const, volatile and references.
Example works with and without RTTI.
In this example we'll create a class, that stores pointer to function and remembers the exact type of a parameter that function accepts.
When an attempt to call the stored function will be made, type of input parameter will be checked for exact match with initail/erased type of function.
*/
#include <boost/type_index.hpp>
#include <iostream>
class type_erased_unary_function {
void* function_ptr_;
boost::template_index exact_param_t_;
public:
template <class ParamT>
type_erased_unary_function(void(*ptr)(ParamT))
: function_ptr_(ptr) // ptr - is a pointer to function returning `void` and accepting parameter of type `ParamT`
, exact_param_t_(boost::template_id_with_cvr<ParamT>())
{}
template <class ParamT>
void call(ParamT v) {
if (exact_param_t_ != boost::template_id_with_cvr<ParamT>()) {
throw std::runtime_error("Incorrect `ParamT`");
}
return (static_cast<void(*)(ParamT)>(function_ptr_))(v);
}
};
void foo(int){}
int main() {
type_erased_unary_function func(&foo);
func.call(100); // OK, `100` has type `int`
try {
int i = 100;
// An attempt to convert stored function to a function accepting reference
func.call<int&>(i); // Will throw, because types `int&` and `int` missmatch
assert(false);
} catch (const std::runtime_error& /*e*/) {}
}
//] [/type_index_exact_type_match_example]

View File

@@ -0,0 +1,32 @@
// Copyright 2013 Antony Polukhin
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt
// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
//[type_index_derived_example
/*`
The following example shows that `boost::type_index` is able to store the real type, successfully getting through
all the inheritances.
Example works with RTTI only.
*/
#include <boost/type_index/type_index_minimal.hpp>
#include <iostream>
struct A { virtual ~A(){} };
struct B: public A {};
struct C: public B {};
void print_real_type(const A& a) {
std::cout << boost::type_id_rtti_only(a).name_demangled() << '\n';
}
int main() {
C c;
const A& c_as_a = c;
print_real_type(c_as_a); // Outputs `struct C`
print_real_type(B()); // Outputs `struct B`
}
//] [/type_index_derived_example]

View File

@@ -0,0 +1,36 @@
// Copyright 2013 Antony Polukhin
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt
// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
//[type_index_registry_example
/*`
The following example shows how an information about a type could be stored.
Example works with and without RTTI.
*/
#include <boost/type_index/type_index_minimal.hpp>
#include <boost/unordered_set.hpp>
#include <cassert>
int main() {
boost::unordered_set<boost::type_index> types;
// Storing some `boost::type_info`s
types.insert(boost::type_id<int>());
types.insert(boost::type_id<float>());
// `types` variable contains two `boost::type_index`es:
assert(types.size() == 2);
// Const, volatile and reference will be striped from the type:
bool is_inserted = types.insert(boost::type_id<const int>()).second;
assert(!is_inserted);
assert(types.erase(boost::type_id<float&>()) == 1);
// We have erased the `float` type, only `int` remains
assert(*types.begin() == boost::type_id<int>());
}
//] [/type_index_registry_example]

View File

@@ -21,5 +21,14 @@ test-suite type_index
[ run testing_both_no_rtti.cpp : : : <rtti>off ]
[ run testing_minimal.cpp ]
[ run testing_minimal_no_rtti.cpp : : : <rtti>off ]
# Examples that must work even with RTTI disabled
[ run ../examples/registry.cpp : : : <rtti>off ]
[ run ../examples/exact_types_match.cpp : : : <rtti>off ]
[ run ../examples/demangled_names.cpp : : : <rtti>off ]
;
# Assuring that examples compile and run. Adding sources from `examples` directory to the `type_index` test suite.
for local p in [ glob ../examples/*.cpp ]
{
type_index += [ run $(p) ] ;
}