diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2
new file mode 100755
index 0000000..734ecdf
--- /dev/null
+++ b/doc/Jamfile.v2
@@ -0,0 +1,7 @@
+#project boost/doc ;
+project root ;
+
+import boostbook : boostbook ;
+
+boostbook typeof : typeof.xml ;
+
diff --git a/doc/project-root.jam b/doc/project-root.jam
new file mode 100755
index 0000000..41c3a0d
--- /dev/null
+++ b/doc/project-root.jam
@@ -0,0 +1,6 @@
+
+path-constant BOOST_ROOT : . ;
+
+#using lex ;
+#using bison ;
+#using testing ;
diff --git a/doc/typeof.qbk b/doc/typeof.qbk
new file mode 100755
index 0000000..6a86c26
--- /dev/null
+++ b/doc/typeof.qbk
@@ -0,0 +1,871 @@
+[library Typeof
+ [authors [Vertleyb, Arkadiy], [Holt, Peder]]
+ [copyright 2004 2005 Arkadiy Vertleyb, Peder Holt]
+ [license
+ 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
+ )
+ ]
+]
+
+[xinclude catalog.xml]
+
+[section:moti Motivation]
+
+[c++]
+
+Today many template libraries supply object generators to simplify object creation
+by utilizing the C++ template argument deduction facility. Consider `std::pair`.
+In order to instantiate this class template and create a temporary object of this instantiation,
+one has to supply both type parameters and value parameters:
+
+ std::pair(5, 3.14159);
+
+To avoid this duplication, STL supplies the `std::make_pair` object generator.
+When it is used, the types of template parameters are deduced from supplied function arguments:
+
+ std::make_pair(5, 3.14159);
+
+For the temporary objects it is enough. However, when a named object needs to be allocated,
+the problem appears again:
+
+ std::pair p(5, 3.14159);
+
+The object generator no longer helps:
+
+ std::pair p = std::make_pair(5, 3.14159);
+
+It would be nice to deduce the type of the object (on the left) from the expression
+it is initialized with (on the right), but the current C++ syntax does not allow for this.
+
+The above example demonstrates the essence of the problem but does not demonstrate its scale.
+Many libraries, especially expression template libraries, create objects of really complicated types,
+and go a long way to hide this complexity behind object generators. Consider a nit Boost.Lambda functor:
+
+ _1 > 15 && _2 < 20
+
+If one wanted to allocate a named copy of such an innocently looking functor,
+she would have to specify something like this:
+
+ lambda_functor<
+ lambda_functor_base<
+ logical_action,
+ tuple<
+ lambda_functor<
+ lambda_functor_base<
+ relational_action,
+ tuple<
+ lambda_functor >,
+ int const
+ >
+ >
+ >,
+ lambda_functor<
+ lambda_functor_base<
+ relational_action,
+ tuple<
+ lambda_functor >,
+ int const
+ >
+ >
+ >
+ >
+ >
+ >
+ f = _1 > 15 && _2 < 20;
+
+
+Not exactly elegant. To solve this problem, the C++ standard committee is considering
+a few additions to the standard language, such as `typeof/decltype` and `auto` (see
+[@http://www.osl.iu.edu/~jajarvi/publications/papers/decltype_n1478.pdf
+http://www.osl.iu.edu/~jajarvi/publications/papers/decltype_n1478.pdf]).
+
+The `typeof` operator (or `decltype`, which is a slightly different flavor of `typeof`)
+allows one to determine the type of an expression at compile time. Using `typeof`,
+the above example can be simplified drastically:
+
+ typeof(_1 > 15 && _2 < 20) f = _1 > 15 && _2 < 20;
+
+Much better, but some duplication still exists. The `auto` type solves the rest of the problem:
+
+ auto f = _1 > 15 && _2 < 20;
+
+[endsect]
+
+[section:tuto Tutorial]
+
+To deduce the type of an expression at compile time
+use the `BOOST_TYPEOF` macro:
+
+ namespace ex1
+ {
+ typedef BOOST_TYPEOF(1 + 0.5) type;
+
+ BOOST_STATIC_ASSERT((is_same::value));
+ }
+
+In the dependent context use `BOOST_TYPEOF_TPL` instead of `BOOST_TYPEOF`:
+
+ namespace ex2
+ {
+ template
+ BOOST_TYPEOF_TPL(T() + U()) add(const T& t, const U& u)
+ {
+ return t + u;
+ };
+
+ typedef BOOST_TYPEOF(add('a', 1.5)) type;
+
+ BOOST_STATIC_ASSERT((is_same::value));
+ }
+
+The above examples are possible because the Typeof Library knows about
+primitive types, such as `int`, `double`, `char`, etc. The Typeof Library also
+knows about most types and templates defined by the
+Standard C++ Library, but the appropriate headers need to be included
+to take advantage of this:
+
+ #include
+
+ namespace ex3
+ {
+ BOOST_AUTO(p, make_pair(1, 2));
+
+ BOOST_STATIC_ASSERT((is_same >::value));
+ }
+
+Here `` includes `` and contains
+knowledge about templates defined there. This naming convention
+applies in general, for example to let the Typeof Library handle `std::vector`,
+include ``, etc.
+
+To deduce the type of a variable from the expression, this variable
+is initialized with, use the `BOOST_AUTO` macro (or `BOOST_AUTO_TPL`
+in a dependent context:
+
+ #include
+
+ namespace ex4
+ {
+ BOOST_AUTO(p, new int[20]);
+
+ BOOST_STATIC_ASSERT((is_same::value));
+ }
+
+Both `BOOST_TYPEOF` and `BOOST_AUTO` strip top-level qualifiers.
+Therefore, to allocate a reference, this has to be defined explicitly:
+
+ namespace ex5
+ {
+ string& hello()
+ {
+ static string s = "hello";
+ return s;
+ }
+
+ BOOST_AUTO(&s, hello());
+ }
+
+To better understand this syntax, note that this gets expanded into:
+
+ BOOST_TYPEOF(hello()) &s = hello();
+
+If your define your own type, the Typeof Library cannot handle it
+unless you let it know about this type. You tell the Typeof Library
+about a type (or template) by the means of "registering" this type/template.
+
+Any source or header file where types/templates are registered should
+contain the following line before any registration is done:
+
+ #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+After this a type can be registered:
+
+ namespace ex6
+ {
+ struct MyType
+ {};
+ }
+
+ BOOST_TYPEOF_REGISTER_TYPE(ex6::MyType)
+
+The registration should be done from the context of global namespace;
+fully qualified type name has to be used.
+
+Any number of types can be registered in one file, each on a separate line.
+
+Once your type is registered, the Typeof Library can handle it in any context:
+
+ namespace ex6
+ {
+ typedef BOOST_TYPEOF(make_pair(1, MyType())) type;
+
+ BOOST_STATIC_ASSERT((is_same >::value));
+ }
+
+A template is registered by specifying its fully qualified name,
+and describing its parameters. In the simplest case, when all parameters
+are type parameters, only their number needs to be specified:
+
+ namespace ex7
+ {
+ template
+ struct MyTemplate
+ {};
+ }
+
+ BOOST_TYPEOF_REGISTER_TEMPLATE(ex7::MyTemplate, 2)
+
+ namespace ex7
+ {
+ typedef BOOST_TYPEOF(make_pair(1, MyTemplate())) type;
+
+ BOOST_STATIC_ASSERT((is_same >
+ >::value));
+ }
+
+When a template has integral template parameters, all parameters need
+to be described in the preprocessor sequence:
+
+ namespace ex8
+ {
+ template
+ struct MyTemplate
+ {};
+ }
+
+ BOOST_TYPEOF_REGISTER_TEMPLATE(ex8::MyTemplate, (class)(int))
+
+ namespace ex8
+ {
+ typedef BOOST_TYPEOF(make_pair(1, MyTemplate, 0>())) type;
+
+ BOOST_STATIC_ASSERT((is_same, 0> >
+ >::value));
+ }
+
+Please see the reference for more details.
+
+[endsect]
+
+[section:refe Reference]
+
+[section:auto AUTO, AUTO_TPL]
+
+The `BOOST_AUTO` macro emulates the proposed `auto` keyword in C++.
+
+[h4 Usage]
+
+ BOOST_AUTO(var,expr)
+ BOOST_AUTO_TPL(var,expr)
+
+[variablelist Arguments
+[[var][a free identifier]]
+[[expr][a valid c++ expression that has a type]]
+]
+
+[h4 Remarks]
+
+If you want to use `auto` in a template-context, use `BOOST_AUTO_TPL(expr)`,
+which takes care of `typename` inside the `auto` expression.
+
+[h4 Sample Code]
+
+ void main()
+ {
+ length::meter a(5);
+ force::newton b(6);
+ BOOST_AUTO(c, a * b);
+ }
+
+[endsect]
+
+[section:compl COMPLIANT]
+
+The `BOOST_TYPEOF_COMPLIANT` macro can be used to force the emulation mode.
+Define it if your compiler by default uses another mode, such as native `typeof`
+or Microsoft-specific trick, but you want to use the emulation mode,
+for example for portability reasons.
+
+[endsect]
+
+[section:incr INCREMENT_REGISTRATION_GROUP]
+
+The `BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP` macro ensures that type registrations
+in different header files receive unique identifiers.
+
+[h4 Usage]
+
+ #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+[h4 Remarks]
+
+specified once in every cpp/hpp file where any registration is performed,
+before any registration.
+
+[h4 Sample Code]
+
+ #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+ class X;
+ BOOST_TYPEOF_REGISTER_TYPE(X)
+
+[endsect]
+
+[section:inte INTEGRAL]
+
+The `BOOST_TYPEOF_INTEGRAL` macro is used when registering an integral
+template parameter using `BOOST_TYPEOF_REGISTER_TEMPLATE`.
+
+Useful for `enum`s and dependent integral template parameters.
+
+[h4 Usage]
+
+ BOOST_TYPEOF_INTEGRAL(x)
+
+[variablelist Arguments
+[[x][a fully qualified integral type or enum]]
+]
+
+[h4 Remarks]
+
+A short syntax has been implemented for the built in types
+(int, bool, long, unsigned long, etc.)
+
+[h4 Sample Code]
+
+ #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+ namespace foo
+ {
+ enum color {red, green, blue};
+
+ template
+ class class_with_enum {};
+
+ template
+ class class_with_dependent_non_type {};
+ }
+
+ BOOST_TYPEOF_REGISTER_TEMPLATE(foo::class_with_enum,
+ (BOOST_TYPEOF_INTEGRAL(foo::color))
+ (typename)
+ )
+
+ BOOST_TYPEOF_REGISTER_TEMPLATE(foo::class_with_dependent_non_type,
+ (typename)
+ (BOOST_TYPEOF_INTEGRAL(P0))
+ )
+
+[endsect]
+
+[section:limit_func LIMIT_FUNCTION_ARITY]
+
+The `BOOST_TYPEOF_LIMIT_FUNCTION_ARITY` macro defines how many parameters
+are supported for functios, and applies to functions, function pointers,
+function references, and member function pointers. The default value is 10.
+Redefine if you want the Typeof Library to handle functions with more parameters.
+
+[endsect]
+
+[section:limit_size LIMIT_SIZE]
+
+The `BOOST_TYPEOF_LIMIT_SIZE` macro defines the size of the compile-time sequence
+used to encode a type. The default value is 50. Increase it if you want
+the Typeof Library to handle very complex types, although this
+possibility is limited by the maximum number of template parameters supported
+by your compiler. On the other hand, if you work only with very simple types,
+decreasing this number may help to boost compile-time performance.
+
+[endsect]
+
+[section:lval LVALUE_TYPEOF]
+
+The `BOOST_LVALUE_TYPEOF` macro preserves the L-valueness of an expression.
+
+[h4 Usage]
+
+ BOOST_LVALUE_TYPEOF(expr)
+
+[variablelist Arguments
+[[expr][a valid c++ expression that has a type]]
+]
+
+[h4 Remarks]
+
+This macro attempts to emulate the `decltype`. Its rules, however,
+are directly built on the rules of binding a reference, and therefore
+differ from the ones of real `decltype`:
+
+[table rules of LVALUE_TYPEOF
+[[expr][decltype][LVALUE_TYPEOF]]
+[[int i;][int][int&]]
+[[const int ci = 0;][const int][const int&]]
+[[int& ri = i;][int&][int&]]
+[[const int& cri = ci;][const int&][const int&]]
+[[int foo();][int][int]]
+[[const int foo();][const int][const int&]]
+[[int& foo();][int&][int&]]
+[[const int& foo();][const int&][const int&]]
+[[21][int][compiler-dependent]]
+[[int(21)][int][int]]
+]
+
+[h4 Sample Code]
+
+ int& get_value(int& a);
+ int get_value(const double& a);
+
+ void main()
+ {
+ int a=5;
+ typedef BOOST_LVALUE_TYPEOF(get_value(a)) type;
+ }
+
+[endsect]
+
+[section:regtype REGISTER_TYPE]
+
+The `BOOST_TYPEOF_REGISTER_TYPE` macro informs the Typeof Library
+about the existence of a type
+
+[h4 Usage]
+
+ BOOST_TYPEOF_REGISTER_TYPE(x)
+
+[variablelist Arguments
+[[x][a fully qualified type]]
+]
+
+[h4 Remarks]
+
+Must be used in the global namespace
+
+[h4 Sample Code]
+
+ #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+ namespace foo
+ {
+ class bar {};
+ enum color {red, green, blue};
+ }
+
+ BOOST_TYPEOF_REGISTER_TYPE(foo::bar)
+ BOOST_TYPEOF_REGISTER_TYPE(foo::color)
+
+[endsect]
+
+[section:regtemp REGISTER_TEMPLATE]
+
+The `BOOST_TYPEOF_REGISTER_TEMPLATE` macro informs the Typeof Library
+about the existence of a template and describes its parameters
+
+[h4 Usage]
+
+ BOOST_TYPEOF_REGISTER_TEMPLATE(x, n)
+ BOOST_TYPEOF_REGISTER_TEMPLATE(x, seq)
+
+[variablelist Arguments
+[[x][a fully qualified template]]
+[[n][the number of template arguments. Only valid if all template arguments are typenames]]
+[[seq][a sequence of template arguments. Must be used when integral or template template parameters are present]]
+]
+
+[h4 Remarks]
+
+Must be used in the global namespace.
+
+The library allows registration of templates with type, integral,
+and template template parameters:
+
+* A type template parameter is described by the `(class)` or `(typename)` sequence element
+* A template parameter of a well-known integral type can be described by
+simply supplying its type, like `(unsigned int)`.
+The following well-known integral types are supported:
+ * `[signed/unsigned] char`
+ * `[unsigned] short`
+ * `[unsigned] int`
+ * `[unsigned] long`
+ * `unsigned`
+ * `bool`
+ * `size_t`
+* Other integral types, such as enums, need to be described explicitly
+with the `BOOST_TYPEOF_INTEGRAL` macro, like `(BOOST_TYPEOF_INTEGRAL(MyEnum))`
+* Template template parameters are described with the `BOOST_TYPEOF_TEMPLATE` macro,
+like: `(BOOST_TYPEOF_TEMPLATE((class)(unsigned int)))`.
+In case of all type parameters this can be shortened to something like `(BOOST_TYPEOF_TEMPLATE(2))`.
+The nested template template parameters are not supported.
+
+[h4 Sample Code]
+
+ #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+ namespace foo
+ {
+ template
+ class simple_template {};
+
+ template
+ class class_with_integral_constant {};
+ }
+
+ BOOST_TYPEOF_REGISTER_TEMPLATE(foo::simple_template, 2)
+ BOOST_TYPEOF_REGISTER_TEMPLATE(foo::class_with_integral_constant, (typename)(int))
+
+[endsect]
+
+[section:temp TEMPLATE]
+
+The `BOOST_TYPEOF_TEMPLATE` macro is used when registering template template parameters
+using `BOOST_TYPEOF_REGISTER_TEMPLATE`.
+
+[h4 Usage]
+
+ BOOST_TYPEOF_TEMPLATE(n)
+ BOOST_TYPEOF_TEMPLATE(seq)
+
+[variablelist Arguments
+[[n][the number of template arguments. Only valid if all template arguments are typenames]]
+[[seq][a sequence of template arguments. Must be used when there are integral constants in the nested template]]
+]
+
+[h4 Remarks]
+
+Can not be used to register nested template template parameters.
+
+[h4 Sample Code]
+
+ #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+ namespace foo
+ {
+ enum color {red, green, blue};
+
+ template class T1>
+ class nested_template_class {};
+
+ template class T1>
+ class nested_with_integral {};
+ }
+
+ BOOST_TYPEOF_REGISTER_TEMPLATE(foo::nested_template_class,
+ (foo::color)
+ (BOOST_TYPEOF_TEMPLATE(1))
+ )
+
+ BOOST_TYPEOF_REGISTER_TEMPLATE(foo::nested_with_integral,
+ (BOOST_TYPEOF_TEMPLATE((typename)(unsigned char)))
+ )
+
+[endsect]
+
+[section:typo TYPEOF, TYPEOF_TPL]
+
+The `BOOST_TYPEOF` macro calculates the type of an expression,
+but removes the top-level qualifiers, `const&`
+
+[h4 Usage]
+
+ BOOST_TYPEOF(expr)
+ BOOST_TYPEOF_TPL(expr)
+
+[variablelist Arguments
+[[expr][a valid c++ expression that has a type]]
+]
+
+[h4 Remarks]
+
+If you want to use `typeof` in a template-context, use `BOOST_TYPEOF_TPL(expr)`,
+which takes care of `typename` inside the `typeof` expression.
+
+[h4 Sample Code]
+
+ template
+ struct result_of_conditional
+ {
+ typedef BOOST_TYPEOF_TPL(true?A():B()) type;
+ };
+
+ template
+ result_of_conditional::type min(const A& a,const B& b)
+ {
+ return a < b ? a : b;
+ }
+
+[endsect]
+
+[endsect]
+
+[section:other Other considerations and tips]
+
+[section:natem Native typeof support and emulation]
+
+Many compilers support typeof already, most noticeable GCC and Metrowerks.
+
+Igor Chesnokov recently discovered a method that allows to implement `typeof`
+on the VC series of compilers. It uses a bug in the Microsoft compiler
+that allows a nested class of base to be defined in a class derived from base:
+
+ template struct typeof_access
+ {
+ struct id2type; //not defined
+ };
+
+ template struct typeof_register : typeof_access
+ {
+ // define base's nested class here
+ struct typeof_access::id2type
+ {
+ typedef T type;
+ };
+ };
+
+ //Type registration function
+ typeof_register register_type(const T&);
+
+ //Actually register type by instantiating typeof_register for the correct type
+ sizeof(register_type(some-type));
+
+ //Use the base class to access the type.
+ typedef typeof_access::id2type::type type;
+
+This method has also been adapted to VC7.0, where the nested class
+is a template class that is specialized in the derived class.
+The loopholes have been fixed in VC8.0 though, so on this compiler
+this method doesn't work.
+
+For this and many other compilers neither native `typeof` support
+nor the trick described above is an option. For such compilers
+the emulation method is the only way of implementing `typeof`.
+
+According to a rough estimate, at the time of this writing
+the introduction of the `typeof`, `auto`, etc., into the C++ standard
+may not happen soon. Even after it's done, some time still has to pass
+before most compilers implement this feature. But even after that,
+there always are legacy compilers to support (for example now, in 2005,
+many people are still using VC6, long after VC7.x, and even VC8.0 beta became available).
+
+Considering extreme usefulness of the feature right now,
+it seems to make sense to implement it at the library level.
+
+The emulation mode seems to be important even if a better option is present
+on some particular compiler. If a library author wants to develop portable
+code using `typeof`, she needs to use emulation mode and register her types and
+templates. Those users who have a better option can still take
+advantage of it, since the registration macros are defined as no-op on
+such compilers, while the users for whom emulation is the only option will use it.
+
+The other consideration applies to the users of VC7.1. Even though the more
+convenient `typeof` trick is available, the possibility of upgrade to VC8,
+where emulation remains the only option, should be considered.
+
+The emulation mode can be forced on the compilers that don't use it
+by default by defining the `BOOST_TYPEOF_COMPLIANT` symbol:
+
+ g++ -D BOOST_TYPEOF_COMPLIANT -I \boost\boost_1_32_0 main.cpp
+
+[endsect]
+
+[section:parties The three participating parties]
+
+The Lambda example from the Motivation section requires the following registration:
+
+ #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+ BOOST_TYPEOF_REGISTER_TEMPLATE(boost::tuples::tuple, 2);
+ BOOST_TYPEOF_REGISTER_TEMPLATE(boost::lambda::lambda_functor, 1);
+ BOOST_TYPEOF_REGISTER_TEMPLATE(boost::lambda::lambda_functor_base, 2);
+ BOOST_TYPEOF_REGISTER_TEMPLATE(boost::lambda::relational_action, 1);
+ BOOST_TYPEOF_REGISTER_TEMPLATE(boost::lambda::logical_action, 1);
+ BOOST_TYPEOF_REGISTER_TEMPLATE(boost::lambda::other_action, 1);
+ BOOST_TYPEOF_REGISTER_TYPE(boost::lambda::greater_action);
+ BOOST_TYPEOF_REGISTER_TYPE(boost::lambda::less_action);
+ BOOST_TYPEOF_REGISTER_TYPE(boost::lambda::and_action);
+ BOOST_TYPEOF_REGISTER_TEMPLATE(boost::lambda::placeholder, (int));
+
+It may seem that the price for the ability to discover the expression's type
+is too high: rather large amount of registration is required.
+However note that all of the above registration is done only once,
+and after that, any combination of the registered types and templates
+would be handled. Moreover, this registration is typically done
+not by the end-user, but rather by a layer on top of some library
+(in this example -- Boost.Lambda).
+
+When thinking about this, it's helpful to consider three parties: the typeof facility,
+the library (probably built on expression templates principle), and the end-user.
+The typeof facility is responsible for registering fundamental types.
+The library can register its own types and templates.
+
+In the best-case scenario, if the expressions always consist of only
+fundamental types and library-defined types and templates, a library author
+can achieve the impression that the `typeof` is natively supported for her library.
+On the other hand, the more often expressions contain user-defined types,
+the more responsibility is put on the end-user, and therefore the less attractive
+this approach becomes.
+
+Thus, the ratio of user-defined types in the expressions should be the main
+factor to consider when deciding whether or not to apply the typeof facility.
+
+[endsect]
+
+[section:features Supported features]
+
+The Typeof library pre-registers fundamental types. For these types,
+and for any other types/templates registered by the user library or end-user,
+any combination of the following is supported:
+
+* Pointers;
+* References (except top-level);
+* Consts (except top-level);
+* Volatiles (except top-level);
+* Arrays;
+* Functions, function pointers, and references;
+* Pointers to member functions;
+* Pointers to data members.
+
+For example the following type:
+
+ int& (*)(const volatile char*, double[5], void(*)(short))
+
+is supported right away, and something like:
+
+ void (MyClass::*)(int MyClass::*, MyClass[10]) const
+
+is supported provided `MyClass` is registered.
+
+The Typeof Library also provides registration files for most STL classes/templates.
+These files are located in the std subdirectory, and named after corresponding STL headers.
+These files are not included by the typeof system and have to be explicitly included
+by the user, as needed:
+
+ #include
+ BOOST_AUTO(fun, std::bind2nd(std::less(), 21)); //create named function object for future use.
+
+[endsect]
+
+[section:what What needs to be registered?]
+
+It is possible to take advantage of the compiler when registering types for the Typeof Library.
+Even though there is currently no direct support for typeof in the language,
+the compiler is aware of what the type of an expression is, and gives an error
+if it encounters an expression that has not been handled correctly. In the `typeof` context,
+this error message will contain clues to what types needs to be registered with the
+Typeof Library in order for `BOOST_TYPEOF` to work.
+
+ struct X {};
+
+ template
+ struct Y {};
+
+ std::pair > a;
+
+ BOOST_AUTO(a,b);
+
+We get the following error message from VC7.1
+
+[pre
+ error C2504: 'boost::type_of::'anonymous-namespace'::encode_type_impl' : base
+ class undefined
+ with
+ \[
+ V=boost::type_of::'anonymous-namespace'::encode_type_impl,std::pair>>::V0,
+ Type_Not_Registered_With_Typeof_System=X
+ \]
+]
+
+Inspecting this error message, we see that the compiler complains about `X`
+
+ BOOST_TYPEOF_REGISTER_TYPE(X); //register X with the typeof system
+
+Recompiling, we get a new error message from VC7.1
+
+[pre
+ error C2504: 'boost::type_of::'anonymous-namespace'::encode_type_impl' : base
+ class undefined
+ with
+ \[
+ V=boost::type_of::'anonymous-namespace'::encode_type_impl,std::pair>>::V1,
+ Type_Not_Registered_With_Typeof_System=Y
+ \]
+]
+
+Inspecting this error message, we see that the compiler complains about `Y`.
+Since `Y` is a template, and contains integral constants, we need to take more care when registering:
+
+ BOOST_TYPEOF_REGISTER_TEMPLATE(Y,(typename)(bool)); //register template class Y
+
+It is a good idea to look up the exact definition of `Y` when it contains integral constants.
+For simple template classes containing only typenames, you can rely solely on the compiler error.
+
+The above code now compiles.
+
+This technique can be used to get an overview of which types needs to be registered
+for a given project in order to support `typeof`.
+
+[endsect]
+
+[section:comp Compilers]
+
+The system has been tested with the following compilers:
+
+* MSVC 6.5/7.0/7.1/8.0;
+* GCC 3.4.2
+
+[endsect]
+
+[section:limi Limitations]
+
+Nested template template parameters are not supported, like:
+
+ template class> class Tpl>
+ class A; // can't register!
+
+Classes and templates nested inside other templates also can't be registered
+because of the issue of nondeduced context. This limitation is most noticeable
+with regards to standard iterators in Dinkumware STL, which are implemented
+as nested classes. Instead, instantiations can be registered:
+
+ BOOST_TYPEOF_REGISTER_TYPE(std::list::const_iterator)
+
+[endsect]
+
+[endsect]
+
+[section:cont Contributed By:]
+
+* Compliant compilers -- Arkadiy Vertleyb, Peder Holt
+* MSVC 6.5, 7.0, 7.1 -- Igor Chesnokov, Peder Holt
+
+[endsect]
+
+[section:ackn Acknoledgements]
+
+The idea of representing a type as multiple compile-time integers,
+and passing these integers across function boundaries using sizeof(),
+was taken from Steve Dewhurst's article "A Bitwise typeof Operator", CUJ 2002.
+This article can also be viewed online, at [@http://www.semantics.org/localarchive.html
+http://www.semantics.org/localarchive.html].
+
+Special thank you to Paul Mensonides, Vesa Karvonen, and Aleksey Gurtovoy
+for the Boost Preprocessor Library and MPL. Without these two libraries,
+this typeof implementation would not exist.
+
+The following people provided support, gave valuable comments,
+or in any other way contributed to the library development
+(in alphabetical order):
+
+* David Abrahams
+* Andrey Beliakov
+* Joel de Guzman
+* Daniel James
+* Vesa Karvonen
+* Paul Mensonides
+* Alexander Nasonov
+* Martin Wille
+
+[endsect]
diff --git a/include/boost/typeof/encode_decode.hpp b/include/boost/typeof/encode_decode.hpp
index 2ddbc1e..67bf9e5 100644
--- a/include/boost/typeof/encode_decode.hpp
+++ b/include/boost/typeof/encode_decode.hpp
@@ -25,8 +25,8 @@ namespace boost{namespace type_of{namespace{
template
struct decode_type : decode_type_impl<
- typename mpl::deref::type,
- typename mpl::next::type
+ typename Iter::type,
+ typename Iter::next
>
{};
}}}
diff --git a/include/boost/typeof/encode_decode_params.hpp b/include/boost/typeof/encode_decode_params.hpp
index 73dc5a7..1b019f6 100644
--- a/include/boost/typeof/encode_decode_params.hpp
+++ b/include/boost/typeof/encode_decode_params.hpp
@@ -28,7 +28,7 @@
#define BOOST_TYPEOF_ENCODE_PARAMS(n, ID) \
BOOST_PP_REPEAT(n, BOOST_TYPEOF_ENCODE_PARAMS_BEGIN, ~) \
- typename mpl::push_back >::type \
+ typename push_back >::type \
BOOST_PP_REPEAT(n, BOOST_TYPEOF_ENCODE_PARAMS_END, ~)
#endif//BOOST_TYPEOF_ENCODE_DECODE_PARAMS_HPP_INCLUDED
diff --git a/include/boost/typeof/int_encoding.hpp b/include/boost/typeof/int_encoding.hpp
index 4763cef..667c683 100644
--- a/include/boost/typeof/int_encoding.hpp
+++ b/include/boost/typeof/int_encoding.hpp
@@ -53,14 +53,14 @@ namespace boost{namespace type_of{
////////////////////////////////
template= 0x3fffffff)>
- struct encode_size_t : mpl::push_back<
+ struct encode_size_t : push_back<
V,
boost::mpl::size_t::value>
>
{};
template
- struct encode_size_t : mpl::push_back : push_back::value> >::type,
boost::mpl::size_t
@@ -86,22 +86,22 @@ namespace boost{namespace type_of{
template
struct decode_size_t
{
- enum {m = boost::mpl::deref::type::value};
+ enum {m = Iter::type::value};
enum {value = (size_t)m * 0x3ffffffe + n};
- typedef typename boost::mpl::next::type iter;
+ typedef typename Iter::next iter;
};
template
struct decode_integral
{
- enum {m = boost::mpl::deref::type::value};
+ enum {m = Iter::type::value};
enum {n = unpack::value};
enum {overflow = unpack::overflow};
- typedef typename boost::mpl::next::type nextpos;
+ typedef typename Iter::next nextpos;
static const T value = (T)(size_t)decode_size_t::value;
diff --git a/include/boost/typeof/modifiers.hpp b/include/boost/typeof/modifiers.hpp
index 504921f..45c806d 100644
--- a/include/boost/typeof/modifiers.hpp
+++ b/include/boost/typeof/modifiers.hpp
@@ -16,7 +16,7 @@
{\
typedef\
typename encode_type<\
- typename mpl::push_back<\
+ typename push_back<\
V\
, mpl::size_t >::type\
, T>::type\
@@ -60,8 +60,8 @@ namespace boost{namespace type_of{namespace{
{\
typedef\
typename encode_type<\
- typename mpl::push_back<\
- typename mpl::push_back<\
+ typename push_back<\
+ typename push_back<\
V\
, mpl::size_t >::type\
, mpl::size_t >::type\
@@ -71,8 +71,8 @@ namespace boost{namespace type_of{namespace{
template\
struct decode_type_impl, Iter>\
{\
- enum{n = mpl::deref::type::value};\
- typedef decode_type::type> d;\
+ enum{n = Iter::type::value};\
+ typedef decode_type d;\
typedef typename d::type Qualifier type[n];\
typedef typename d::iter iter;\
}
diff --git a/include/boost/typeof/template_encoding.hpp b/include/boost/typeof/template_encoding.hpp
index e602b4d..c623086 100755
--- a/include/boost/typeof/template_encoding.hpp
+++ b/include/boost/typeof/template_encoding.hpp
@@ -131,7 +131,7 @@
>\
struct encode_type_impl >\
{\
- typedef typename mpl::push_back >::type V0;\
+ typedef typename push_back >::type V0;\
BOOST_PP_SEQ_FOR_EACH_I(BOOST_TYPEOF_REGISTER_TEMPLATE_ENCODE_PARAM, ~, Params)\
typedef BOOST_PP_CAT(V, Size) type;\
};\
diff --git a/include/boost/typeof/template_template_param.hpp b/include/boost/typeof/template_template_param.hpp
index ae4b720..b495106 100644
--- a/include/boost/typeof/template_template_param.hpp
+++ b/include/boost/typeof/template_template_param.hpp
@@ -65,7 +65,7 @@ namespace boost
{};
template struct decode_template
- : decode_template_impl::type, typename mpl::next::type>
+ : decode_template_impl
{};
}
}
@@ -82,7 +82,7 @@ namespace boost
BOOST_PP_ENUM_PARAMS(\
BOOST_PP_SEQ_SIZE(Params),\
P)> >\
- : mpl::push_back >\
+ : push_back >\
{\
};\
template struct decode_template_impl, Iter>\
diff --git a/include/boost/typeof/type_encoding.hpp b/include/boost/typeof/type_encoding.hpp
index cb877f0..07e69f6 100644
--- a/include/boost/typeof/type_encoding.hpp
+++ b/include/boost/typeof/type_encoding.hpp
@@ -8,7 +8,7 @@
#define BOOST_TYPEOF_REGISTER_TYPE_IMPL(T, Id) \
\
template struct encode_type_impl \
- : mpl::push_back > \
+ : push_back > \
{}; \
template struct decode_type_impl, Iter> \
{ \
diff --git a/include/boost/typeof/typeof_impl.hpp b/include/boost/typeof/typeof_impl.hpp
index a4d9ac5..87cca00 100644
--- a/include/boost/typeof/typeof_impl.hpp
+++ b/include/boost/typeof/typeof_impl.hpp
@@ -1,4 +1,5 @@
-// Copyright (C) 2004 Arkadiy Vertleyb
+// Copyright (C) 2004, 2005 Arkadiy Vertleyb
+// Copyright (C) 2005 Peder Holt
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt)
@@ -8,73 +9,46 @@
#include
#include
#include
+#include
-#include
-#include
-#include
-#include
+#define BOOST_TYPEOF_VECTOR(n) BOOST_PP_CAT(boost::type_of::vector, n)
-#ifdef BOOST_TYPEOF_USE_MPL_VECTOR
-# include
-# include
-# define BOOST_TYPEOF_VECTOR(n) BOOST_PP_CAT(boost::mpl::vector, n)
-#else
-# include
-# define BOOST_TYPEOF_VECTOR(n) BOOST_PP_CAT(boost::type_of::vector, n)
-#endif
+#define BOOST_TYPEOF_sizer_item(z, n, _)\
+ char item ## n[V::item ## n ::value];
-namespace boost{namespace type_of{
-
- template
- struct at_result
- {
- typedef typename encode_type, T>::type encoded_type;
- typedef typename mpl::size::type size;
-
- typedef char(&type)[
- mpl::at<
- encoded_type,
- mpl::int_<(pos < size::value) ? pos : 0>
- >::type::value
- ];
- };
+namespace boost { namespace type_of {
- template
- typename at_result::type at(const T&);
+ template
+ struct sizer
+ {
+ // char item0[V::item0::value];
+ // char item1[V::item1::value];
+ // ...
- template
- char(&size(const T&))[
- mpl::size, T>::type>::value
- ];
+ BOOST_PP_REPEAT(BOOST_TYPEOF_LIMIT_SIZE, BOOST_TYPEOF_sizer_item, ~)
+ };
+
+ template
+ sizer, T>::type> encode(const T&);
}}
-#define BOOST_TYPEOF_AT(n, expr) sizeof(boost::type_of::at(expr))
-#define BOOST_TYPEOF_SIZE(expr) sizeof(boost::type_of::size(expr))
+#undef BOOST_TYPEOF_sizer_item
-#ifndef BOOST_TYPEOF_NO_SIMPLE_TYPE_OPTIMIZATION
-# define BOOST_TYPEOF_TYPEITEM(z, n, expr)\
- boost::mpl::size_t
-#else
-# define BOOST_TYPEOF_TYPEITEM(z, n, expr)\
- boost::mpl::size_t
-#endif
+#define BOOST_TYPEOF_TYPEITEM(z, n, expr)\
+ boost::mpl::size_t
-#define BOOST_TYPEOF(Expr) \
- boost::type_of::decode_type< \
- boost::mpl::begin< \
- BOOST_TYPEOF_VECTOR(BOOST_TYPEOF_LIMIT_SIZE)< \
- BOOST_PP_ENUM(BOOST_TYPEOF_LIMIT_SIZE, BOOST_TYPEOF_TYPEITEM, Expr) \
- > \
- >::type \
+#define BOOST_TYPEOF(Expr) \
+ boost::type_of::decode_type< \
+ BOOST_TYPEOF_VECTOR(BOOST_TYPEOF_LIMIT_SIZE)< \
+ BOOST_PP_ENUM(BOOST_TYPEOF_LIMIT_SIZE, BOOST_TYPEOF_TYPEITEM, Expr) \
+ >::begin \
>::type
-#define BOOST_TYPEOF_TPL(Expr) \
- typename boost::type_of::decode_type< \
- typename boost::mpl::begin< \
- BOOST_TYPEOF_VECTOR(BOOST_TYPEOF_LIMIT_SIZE)< \
- BOOST_PP_ENUM(BOOST_TYPEOF_LIMIT_SIZE, BOOST_TYPEOF_TYPEITEM, Expr) \
- > \
- >::type \
+#define BOOST_TYPEOF_TPL(Expr) \
+ typename boost::type_of::decode_type< \
+ typename BOOST_TYPEOF_VECTOR(BOOST_TYPEOF_LIMIT_SIZE)< \
+ BOOST_PP_ENUM(BOOST_TYPEOF_LIMIT_SIZE, BOOST_TYPEOF_TYPEITEM, Expr) \
+ >::begin \
>::type
#endif//BOOST_TYPEOF_COMPLIANT_TYPEOF_IMPL_HPP_INCLUDED
diff --git a/include/boost/typeof/vector.hpp b/include/boost/typeof/vector.hpp
index fe49a42..4731958 100644
--- a/include/boost/typeof/vector.hpp
+++ b/include/boost/typeof/vector.hpp
@@ -1,22 +1,15 @@
// Copyright (C) 2005 Arkadiy Vertleyb
+// Copyright (C) 2005 Peder Holt
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt)
-// Minimal replacement for mpl::vector<>.
-// Works a little faster with VC7.1 and a lot faster with GCC (compliant mode).
-// Define BOOST_TYPEOF_USE_MPL_VECTOR to avoid it and use mpl::vector<> instead.
-
#ifndef BOOST_TYPEOF_VECTOR_HPP_INCLUDED
#define BOOST_TYPEOF_VECTOR_HPP_INCLUDED
-#include
-#include
-#include
-#include
-#include
#include
#include
#include
+#include
#include
#include
#include
@@ -27,87 +20,49 @@
// iterator
-namespace boost{namespace type_of{
- template
- struct v_iter
- {
- typedef typename boost::mpl::at::type type;
- typedef v_iter::type> next;
+#define BOOST_TYPEOF_spec_iter(z, n, _)\
+ template\
+ struct v_iter >\
+ {\
+ typedef typename V::item ## n type;\
+ typedef v_iter > next;\
};
+
+namespace boost{ namespace type_of{
+
+ template struct v_iter; // not defined
+ BOOST_PP_REPEAT(BOOST_TYPEOF_LIMIT_SIZE, BOOST_TYPEOF_spec_iter, ~)
}}
+#undef BOOST_TYPEOF_spec_iter
+
// vector
#define BOOST_TYPEOF_typedef_item(z, n, _)\
typedef P ## n item ## n;
+#define BOOST_TYPEOF_typedef_fake_item(z, n, _)\
+ typedef mpl::int_<1> item ## n;
+
#define BOOST_TYPEOF_define_vector(z, n, _)\
template\
struct vector ## n\
{\
- typedef v_tag tag;\
typedef v_iter > begin;\
- typedef mpl::int_ size;\
BOOST_PP_REPEAT(n, BOOST_TYPEOF_typedef_item, ~)\
+ BOOST_PP_REPEAT_FROM_TO(n, BOOST_TYPEOF_LIMIT_SIZE, BOOST_TYPEOF_typedef_fake_item, ~)\
};
-namespace boost{namespace type_of{
- class v_tag;
+namespace boost{ namespace type_of{
+
BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_TYPEOF_LIMIT_SIZE), BOOST_TYPEOF_define_vector, ~)
}}
#undef BOOST_TYPEOF_typedef_item
+#undef BOOST_TYPEOF_typedef_fake_item
#undef BOOST_TYPEOF_define_vector
-// at (specializing at rather than at_impl gives some performance gain)
-
-#define BOOST_TYPEOF_spec_at(z, n, _)\
- template\
- struct at >\
- {\
- typedef typename V::item ## n type;\
- };
-
-namespace boost{namespace mpl{
- BOOST_PP_REPEAT(BOOST_TYPEOF_LIMIT_SIZE, BOOST_TYPEOF_spec_at, ~)
-}}
-
-/*
-#define BOOST_TYPEOF_spec_at(z, n, _)\
- template\
- struct apply >\
- {\
- typedef typename V::item ## n type;\
- };
-
-namespace boost{namespace mpl{
- template<>
- struct at_impl
- {
- template
- struct apply;
- BOOST_PP_REPEAT(BOOST_TYPEOF_LIMIT_SIZE, BOOST_TYPEOF_spec_at, ~)
- };
-}}
-*/
-
-#undef BOOST_TYPEOF_spec_at
-
-// size
-
-namespace boost{namespace mpl{
- template<>
- struct size_impl
- {
- template
- struct apply
- {
- typedef typename V::size type;
- };
- };
-}}
-
-// push_back (specializing push_back rather than push_back_impl gives some performance gain)
+// push_back
#define BOOST_TYPEOF_spec_push_back(z, n, _)\
template\
@@ -118,31 +73,12 @@ namespace boost{namespace mpl{
> type;\
};
-namespace boost{namespace mpl{
+namespace boost{ namespace type_of{
+
+ template struct push_back; // not defined
BOOST_PP_REPEAT(BOOST_TYPEOF_LIMIT_SIZE, BOOST_TYPEOF_spec_push_back, ~)
}}
-/*
-#define BOOST_TYPEOF_spec_push_back(z, n, _)\
- template\
- struct apply, T>\
- {\
- typedef BOOST_PP_CAT(boost::type_of::vector, BOOST_PP_INC(n))<\
- BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_COMMA_IF(n) T\
- > type;\
- };
-
-namespace boost{namespace mpl{
- template<>
- struct push_back_impl
- {
- template
- struct apply;
- BOOST_PP_REPEAT(BOOST_TYPEOF_LIMIT_SIZE, BOOST_TYPEOF_spec_push_back, ~)
- };
-}}
-*/
-
#undef BOOST_TYPEOF_spec_push_back
#endif//BOOST_TYPEOF_COMPLIANT_VECTOR_HPP_INCLUDED
diff --git a/test/compliant/typeof.vcproj b/test/compliant/typeof.vcproj
index 6695849..0a39908 100755
--- a/test/compliant/typeof.vcproj
+++ b/test/compliant/typeof.vcproj
@@ -324,6 +324,9 @@
RelativePath="..\mpl\register.hpp">
+
+