forked from boostorg/type_index
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:
@@ -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]
|
||||
|
||||
|
||||
|
42
libs/type_index/examples/demangled_names.cpp
Normal file
42
libs/type_index/examples/demangled_names.cpp
Normal 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]
|
56
libs/type_index/examples/exact_types_match.cpp
Normal file
56
libs/type_index/examples/exact_types_match.cpp
Normal 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]
|
32
libs/type_index/examples/inheritance.cpp
Normal file
32
libs/type_index/examples/inheritance.cpp
Normal 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]
|
36
libs/type_index/examples/registry.cpp
Normal file
36
libs/type_index/examples/registry.cpp
Normal 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]
|
@@ -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) ] ;
|
||||
}
|
||||
|
Reference in New Issue
Block a user