diff --git a/generic_programming.html b/generic_programming.html new file mode 100644 index 0000000..9f3f85c --- /dev/null +++ b/generic_programming.html @@ -0,0 +1,175 @@ + + + + + + + + Generic Programming Techniques + + c++boost.gif (8819 bytes) + +

Generic Programming Techniques

+ +

This is an incomplete survey of some of the generic programming + techniques used in the boost libraries. + +

Table of Contents

+ + + +

Traits

+ +

A traits class provides a way of associating information with another + type. For example, the class template std::iterator_traits<T> + looks something like this: + +

+
+template <class Iterator>
+struct iterator_traits {
+  typedef ... iterator_category;
+  typedef ... value_type;
+  typedef ... difference_type;
+  typedef ... pointer;
+  typedef ... reference;
+};
+
+
+ The traits' value_type gives generic code the type which the + iterator is "pointing at", while the iterator_category can be used + to select more efficient algorithms depending on the iterator's + capabilities. + +

A key feature of traits templates is that they're non-intrusive: + they allow us to associate information with arbitrary types, including + built-in types and types defined in third-party libraries, Normally, traits + are specified for a particular type by (partially) specializing the traits + template. + +

For an in-depth description of std::type_traits, see this page provided + by SGI. Another very different expression of the traits idiom in the + standard is std::numeric_limits<T> which provides constants + describing the range and capabilities of numeric types. + +

Type Generators

+ +

A type generator is a template whose only purpose is to + synthesize a single new type based on its template argument(s). The + generated type is usually expressed as a nested typedef named, + appropriately type. A type generator is usually used to + consolidate a complicated type expression into a simple one, as in + boost::filter_iterator_generator, + which looks something like this: + +

+
+template <class Predicate, class Iterator, 
+    class Value = complicated default,
+    class Reference = complicated default,
+    class Pointer = complicated default,
+    class Category = complicated default,
+    class Distance = complicated default
+         >
+struct filter_iterator_generator {
+    typedef iterator_adaptor<
+        Iterator,filter_iterator_policies<Predicate,Iterator>,
+        Value,Reference,Pointer,Category,Distance> type;
+};
+
+
+ +

Now, that's complicated, but producing an adapted filter iterator is + much easier. You can usually just write: + +

+
+boost::filter_iterator_generator<my_predicate,my_base_iterator>::type
+
+
+ +

Object Generators

+ +

An object generator is a function template whose only purpose is + to construct a new object out of its arguments. Think of it as a kind of + generic constructor. An object generator may be more useful than a plain + constructor when the exact type to be generated is difficult or impossible + to express and the result of the generator can be passed directly to a + function rather than stored in a variable. Most object generators are named + with the prefix "make_", after std::make_pair(const T&, const U&). + +

Here is an example, using another standard object generator, std::back_inserter(): + +

+
+// Append the items in [start, finish) to c
+template <class Container, class Iterator>
+void append_sequence(Container& c, Iterator start, Iterator finish)
+{
+   std::copy(start, finish, std::back_inserter(c));
+}
+
+
+ +

Without using the object generator the example above would look like: + write: + +

+
+// Append the items in [start, finish) to c
+template <class Container, class Iterator>
+void append_sequence(Container& c, Iterator start, Iterator finish)
+{
+   std::copy(start, finish, std::back_insert_iterator<Container>(c));
+}
+
+
+ +

As expressions get more complicated the need to reduce the verbosity of + type specification gets more compelling. + +

Policies Classes

+ +

Policies classes are a simple idea we first saw described by Andrei Alexandrescu, but which we + snapped up and quickly applied in the Iterator Adaptors library. A + policies class is a template parameter used to transmit behaviors. A + detailed description by Andrei is available in + this paper. He writes: + +

+

Policy classes are implementations of punctual design choices. They + are inherited from, or contained within, other classes. They provide + different strategies under the same syntactic interface. A class using + policies is templated having one template parameter for each policy it + uses. This allows the user to select the policies needed. + +

The power of policy classes comes from their ability to combine + freely. By combining several policy classes in a template class with + multiple parameters, one achieves combinatorial behaviors with a linear + amount of code. +

+ +

Andrei's description of policies describe their power as being derived + from their granularity and orthogonality. Boost has probably diluted the + distinction in the Iterator + Adaptors library, where we transmit all of an adapted iterator's + behavior in a single policies class. +