...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Section Interface outlines types and functions of the Icl. Synoptical tables allow to review the overall structure of the libraries design and to focus on structural equalities and differences with the corresponding containers of the standard template library.
In the icl we have two groups of interval
types. There are statically bounded
intervals, right_open_interval
,
left_open_interval
,
closed_interval
,
open_interval
, that
always have the the same kind of interval borders and dynamically bounded intervals, discrete_interval
, continuous_interval
which
can have one of the four possible bound types at runtime.
Table 1.6. Interval class templates
group |
form |
template |
instance parameters |
---|---|---|---|
statically bounded |
asymmetric |
|
|
|
|
|
|
|
symmetric |
|
|
|
|
|
|
dynamically bounded |
|
|
|
|
|
|
Not every class template works with all domain types. Use interval class templates according the next table.
Table 1.7. Usability of interval class templates for discrete or continuous domain types
group |
form |
template |
discrete |
continuous |
---|---|---|---|---|
statically bounded |
asymmetric |
yes |
yes |
|
|
|
yes |
yes |
|
|
symmetric |
yes |
|
|
|
|
yes |
|
|
dynamically bounded |
|
yes |
|
|
|
|
|
yes |
From a pragmatical point of view, the most important interval class template
of the statically bounded group is right_open_interval
.
For discrete domain types also closed intervals might be convenient. Asymmetric
intervals can be used with continuous domain types but continuous_interval
is the only class template that allows to represent a singleton interval
that contains only one element.
Use continuous_interval
,
if you work with interval containers of countinuous domain types and you
want to be able to handle single values:
typedef interval_set<std::string, std::less, continuous_interval<std::string> > IdentifiersT; IdentifiersT identifiers, excluded; identifiers += continuous_interval<std::string>::right_open("a", "c"); // special identifiers shall be excluded identifiers -= std::string("boost"); cout << "identifiers: " << identifiers << endl; excluded = IdentifiersT(icl::hull(identifiers)) - identifiers; cout << "excluded : " << excluded << endl; //------ Program output: -------- identifiers: {[a,boost)(boost,c)} excluded : {[boost,boost]}
interval
As shown in the example above, you can choose an interval type by instantiating the interval container template with the desired type.
typedef interval_set<std::string, std::less, continuous_interval<std::string> > IdentifiersT;
But you can work with the library default for interval template parameters
as well, which is interval<DomainT,Compare>::type
.
|
interval bounds |
domain_type |
interval_default |
---|---|---|---|
|
static |
|
|
|
dynamic |
discrete |
|
|
|
continuous |
So, if you are always happy with the library default for the interval type, just use
icl::interval<MyDomainT>::type myInterval;
as you standard way of declaring intervals and default parameters for interval containers:
typedef interval_set<std::string> IdentifiersT; IdentifiersT identifiers, excluded; identifiers += interval<std::string>::right_open("a", "c"); . . .
So class template interval
provides a standard way to work with the library default for intervals.
Via interval<D,C>::type
you can declare a default interval. In addition four static functions
T interval<D,C>::right_open(const D&, const D&); T interval<D,C>::left_open(const D&, const D&); T interval<D,C>::closed(const D&, const D&); T interval<D,C>::open(const D&, const D&);
allow to construct intervals of the library default T
= interval<D,C>::type
.
If you
#define BOOST_ICL_USE_STATIC_BOUNDED_INTERVALS
the library uses only statically bounded right_open_interval
as default interval type. In this case, the four static functions above
are also available, but they only move interval borders consistently, if
their domain type is discrete, and create an appropriate right_open_interval
finally:
interval<D,C>::right_open(a,b) == [a, b) -> [a , b ) interval<D,C>:: left_open(a,b) == (a, b] -> [a++, b++) interval<D,C>:: closed(a,b) == [a, b] -> [a , b++) interval<D,C>:: open(a,b) == (a, b) -> [a++, b )
For continuous domain types only the first of the four functions is applicable
that matches the library default for statically bounded intervals: right_open_interval
.
The other three functions can not perform an appropriate tranformation
and will not compile.
The next two tables give an overview over set class templates of the icl.
Table 1.8. Set class templates
group |
template |
instance parameters |
---|---|---|
|
||
|
|
|
|
|
Templates and template parameters, given in the preceding table are described
in detail below. Interval_sets
represent three class templates interval_set
,
separate_interval_set
and split_interval_set
that all have equal template parameters.
Table 1.9. Parameters of set class templates
|
type of elements |
order of elements |
type of intervals |
memory allocation |
---|---|---|---|---|
template parameter |
|
|
|
|
|
|
|
|
|
|
|
|
|
The next two tables give an overview over map class templates of the icl.
Table 1.10. map class templates
group |
template |
instance parameters |
---|---|---|
|
||
|
|
|
|
Templates and template parameters, given in the preceding table are described
in detail below. Interval_maps
represent two class templates interval_map
and split_interval_map
that all have equal template parameters.
Table 1.11. Parameters of map class templates
|
elements |
mapped values |
traits |
order of elements |
aggregation propagation |
intersection propagation |
type of intervals |
memory allocation |
---|---|---|---|---|---|---|---|---|
template parameter |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Using the following placeholders,
D := class DomainT, C := class CodomainT, T := class Traits, cp := template<class D>class Compare = std::less, cb := template<class C>class Combine = icl::inplace_plus, s := template<class C>class Section = icl::inplace_et, I := class IntervalT = icl::interval<D,cp>::type a := template<class>class Alloc = std::allocator
we arrive at a final synoptical matrix of class templates and their parameters.
interval <D, cp, > interval_sets<D, cp, I, a > interval_maps<D, C, T, cp, cb, s, I, a > icl::map <D, C, T, cp, cb, s, a >
The choice of parameters and their positions follow the std::containers as close a possible, so that usage of interval sets and maps does only require minimal additional knowledge.
Additional knowledge is required when instantiating a comparison parameter
Compare
or an allocation
parameter Alloc
. In contrast
to std::containers these have to be instantiated as templates, like e.g.
interval_set<string, german_compare> sections; // 2nd parameter is a template std::set<string, german_compare<string> > words; // 2nd parameter is a type