2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-20 14:42:21 +00:00
Files
fiber/libs/extension/doc/tutorial4.qbk
Oliver Kowalke 39ec793737 initial checkin
2011-02-09 18:41:35 +01:00

95 lines
3.3 KiB
Plaintext

[/ Boost.Extension - fourth tutorial ]
[/ Copyright 2008 Mariano G. Consoni ]
[/ 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) ]
[/ See http://www.boost.org/ for latest version. ]
[section:tutorial04 Tutorial 4 - Multi-type Containers]
There are two types of containers in the library that can hold objects
of heterogeneous types. The _type_map_ is designed for use with
_shared_library_ so that a standard function signature, taking a
_type_map_, can be provided by each shared library, helping to avoid
type safety problems.
The second type, _parameter_map_, is designed for use with reflections
or factories where the type of the function is not known at compile time.
A _parameter_map_ can be passed into such a factory or reflection, and
then searched for needed parameters, and return a list of missing parameters
if necessary.
The _type_map_ is the simplest of the two, as it can hold exactly one
element of each type. It can hold multiple objects, but they will each
be of a different type.
Here's an example showing a _type_map_ holding an `int` and a
`std::map<std::string, std::string>`.
``
using namespace boost::extensions;
// A type_map can hold one of each type, constructed
// as needed.
type_map types;
int& first_int(types.get());
first_int = 100;
// This actually points to the same int as first_int.
int& second_int(types.get());
second_int = 500;
// This will print out 500.
std::cout << "first_int: " << first_int << std::endl;
// Arbitrary default-constructible types can be held in a type_map.
std::map<std::string, std::string>& string_pairs(types.get());
``
Note that pulling an integer out of it twice results in two references
to the same integer. The same occurs with any type placed into the _type_map_.
A _parameter_map_ on the other hand, can hold any number of elements of any
type, and can automatically convert objects to compatible types.
The basic type stored in a _parameter_map_ is a _parameter_. It is possible
to declare a _parameter_ as being convertible to other types.
By default, a `static_cast` is used to convert the types, but any conversion
function can be provided.
``
parameter<int>* p = new parameter<int>(5);
p->converts_to<float>();
p->converts_to<double>();
``
To have a float change to its ceiling when converted to
an integer, one could write:
``
void FloatCeilingToInt(float* f, int* i) {
*i = static_cast<int>(std::ceil(*f));
}
``
``
parameter<float>* p = new parameter<float>(4.9f);
p->converts_to_with_func(&FloatCeilingToInt);
p->cast<int>(); // returns 5
``
Once created, a _parameter_ can be placed into a _parameter_map_,
along with some sort of name. This name can be of arbitrary type:
_parameter_map_ is a specialized _basic_parameter_map_ with the
std::string type as the name, but other types are also possible.
A _parameter_map_ works much like a `std::multi_map` - since it is built
on one. It has a few specialty methods though. It is possible, for instance,
to retrieve all values that match a certain type and name, or the first
value that matches.
``
parameter_map map;
std::vector<generic_parameter<int>*> int_vector(map.get("some_int_name"));
generic_parameter<int>* first_int(map.get_first("some_int_name"));
``
[endsect]