Boost logo

Boost-Commit :

From: chochlik_at_[hidden]
Date: 2008-07-12 13:57:16


Author: matus.chochlik
Date: 2008-07-12 13:57:15 EDT (Sat, 12 Jul 2008)
New Revision: 47361
URL: http://svn.boost.org/trac/boost/changeset/47361

Log:
mirror [0.2.x]
- Documentation update
Added:
   sandbox/mirror/boost.png (contents, props changed)
   sandbox/mirror/libs/mirror/doc/reference.xml (contents, props changed)
   sandbox/mirror/libs/mirror/doc/reference/meta_type.xml (contents, props changed)
   sandbox/mirror/libs/mirror/doc/samples/
   sandbox/mirror/libs/mirror/doc/samples/typenames_naive.xml (contents, props changed)
   sandbox/mirror/libs/mirror/doc/samples/typenames_naive_mirror.xml (contents, props changed)
   sandbox/mirror/libs/mirror/doc/samples/typenames_naive_typeid.xml (contents, props changed)
Text files modified:
   sandbox/mirror/libs/mirror/doc/introduction.xml | 44 +++++++++++++++++++++++++++++++--------
   sandbox/mirror/libs/mirror/doc/mirror.xml | 1
   sandbox/mirror/libs/mirror/example/registering/types.cpp | 1
   3 files changed, 37 insertions(+), 9 deletions(-)

Added: sandbox/mirror/boost.png
==============================================================================
Binary file. No diff available.

Modified: sandbox/mirror/libs/mirror/doc/introduction.xml
==============================================================================
--- sandbox/mirror/libs/mirror/doc/introduction.xml (original)
+++ sandbox/mirror/libs/mirror/doc/introduction.xml 2008-07-12 13:57:15 EDT (Sat, 12 Jul 2008)
@@ -14,7 +14,7 @@
         The aim of the <libraryname>Mirror</libraryname> library is to provide
         useful meta-data at both compile-time and run-time about common
         C++ constructs like namespaces, types
- (and as a important special case <code>typedef</code>-ined types,
+ (and as a important special case <code>typedef</code>-ined types),
         classes and their base classes and member attributes, instances, etc. and to
         provide uniform and generic interfaces for their introspection.
 </para>
@@ -36,7 +36,7 @@
         (the exceptions to this are explained here).
 </para>
 <para>
- Most important use-cases for the <libraryname>Mirror</libraryname> library
+ Most important features of the <libraryname>Mirror</libraryname> library
         that are currently implemented include:
 </para>
 
@@ -87,8 +87,7 @@
 </itemizedlist>
 
 <para>
- Most important planned use-cases for the <libraryname>Mirror</libraryname> library
- include:
+ Most important <emphasis role="bold">planned</emphasis> features include:
 </para>
 
 <itemizedlist>
@@ -124,7 +123,9 @@
                 to distinguish between various instantiations in the logs. In this case
                 it is very useful if the type name that goes into the log is human-readable
                 and preferrably corresponding to the typename used in the source code.
+ A rather naive implementation could look as follows:
         </para>
+ <xi:include href="samples/typenames_naive.xml"/>
         <para>
                 Another application might want to store its data in a format where the typenames
                 are included (for example as attributes of an XML element) to be able to do
@@ -139,20 +140,25 @@
         <para>
                 The obvious choice if one needs to find out what the name of a given type is is to
                 use the <code>typeid</code> operator and call the <code>name()</code> function
- on the returned reference to <code>type_info</code>. There are however several
- problems with is approach.
+ on the returned reference to <code>type_info</code>. The implementation of our
+ <code>get_typename&lt;T&gt;()</code> function from the previous sample code
+ could be following:
         </para>
+ <xi:include href="samples/typenames_naive_typeid.xml"/>
         <para>
+ There are however, several problems with is approach.
                 The notoriously known issue of <code>type_info::name()</code> is that the string
- returned by this function is implementaion-defined and compilers are free
- to return anything from an empty string, through a mangled typename to a corretly
+ returned by this function is implementation-defined and compilers are free
+ to return anything from an empty string, through a mangled typename to a correctly
                 formatted typename and many of them enjoy this freedom to its full extent.
                 Thus the returned name is not guarenteed to be unique nor human readable or
                 easily understandable, nor is it portable.
+ Some compilers provide functions that demangle the names returned by
+ <code>type_info::name()</code> but again this is not very portable.
         </para>
         <para>
                 One possible solution is the standardisation of the result of <code>typeid(T).name()</code>
- or introduction of a new member function to the <code>type_info</code> structure
+ or introduction of a new standard member function to the <code>type_info</code> structure
                 for example <code>type_info::std_name()</code>,
                 that would return human-readable, unique, portable typenames preferrably corresponding
                 to the C++ typenames.
@@ -165,6 +171,26 @@
                 or even the individual names of the enclosing namespaces or classes
                 separatelly.
         </para>
+ <para>
+ This is when <libraryname>Mirror</libraryname> comes in handy. One of the basic
+ facilities is the <code><classname>meta_type</classname></code> template.
+ Among other things this template has two member functions - <code>base_name</code>
+ and <code>full_name</code> that return the base type name without the nested
+ name specifier and the full type name with the nested name specifier respectively.
+ The names returned by these functions correspond to the C++ typenames, thus
+ are human-readable, unique (if using the <code>full_name</code> member function)
+ and portable.
+ </para>
+ <para>
+ Using <code><classname>meta_type</classname></code> the <code>get_typename&lt;T&gt;()</code>
+ function could look like this:
+ </para>
+ <xi:include href="samples/typenames_naive_mirror.xml"/>
+ <para>
+ With native C++ types and some common types from the <libraryname>STL</libraryname>
+ and from <libraryname>Boost</libraryname> the <code><classname>meta_type</classname></code>
+ works out of the box.
+ </para>
 </section>
 <section id="mirror.motivation.problem.uniformmemattaccess">
         <title>Problem - Uniform access to member attributes of a class' instance</title>

Modified: sandbox/mirror/libs/mirror/doc/mirror.xml
==============================================================================
--- sandbox/mirror/libs/mirror/doc/mirror.xml (original)
+++ sandbox/mirror/libs/mirror/doc/mirror.xml 2008-07-12 13:57:15 EDT (Sat, 12 Jul 2008)
@@ -36,6 +36,7 @@
 
         <xi:include href="introduction.xml"/>
         <xi:include href="tutorial.xml"/>
+ <xi:include href="reference.xml"/>
 
 </library>
 

Added: sandbox/mirror/libs/mirror/doc/reference.xml
==============================================================================
--- (empty file)
+++ sandbox/mirror/libs/mirror/doc/reference.xml 2008-07-12 13:57:15 EDT (Sat, 12 Jul 2008)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+<library-reference>
+ <title>Mirror Reference</title>
+
+ <para>
+ </para>
+ <xi:include href="reference/meta_type.xml"/>
+
+</library-reference>

Added: sandbox/mirror/libs/mirror/doc/reference/meta_type.xml
==============================================================================
--- (empty file)
+++ sandbox/mirror/libs/mirror/doc/reference/meta_type.xml 2008-07-12 13:57:15 EDT (Sat, 12 Jul 2008)
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+<header name="boost/mirror/meta_type.hpp">
+ <namespace name="boost">
+ <namespace name="mirror">
+ <class name="meta_type">
+ <template>
+ <template-type-parameter name="Type"/>
+ </template>
+ <purpose>
+ <para>
+ The purpose of this class template is to provide meta-data
+ about the reflected type, especially to allow to get the
+ base and full type name, of the reflected type and to
+ get information about the scope inside of which this type
+ has been declared.
+ </para>
+ <para>
+ Although the specializations of <code><classname>meta_type</classname></code>
+ template can be used directly to get the meta data about a particular type,
+ it is recomended to use the reflection macros like
+ <code><macroname>BOOST_MIRRORED_TYPE</macroname>(TYPE)</code> or
+ <code><macroname>BOOST_MIRRORED_TYPEOF</macroname>(EXPR)</code>
+ instead, to get the proper specializations of
+ <code><classname>meta_type</classname></code>.
+ </para>
+ </purpose>
+
+ <access name="public">
+ <typedef name="reflected_type">
+ <type>Type</type>
+ <purpose>The reflected type</purpose>
+ <description>
+ <para>The type reflected by this overload of <code><classname>meta_type</classname></code>.
+ </para>
+ </description>
+ </typedef>
+ <typedef name="scope">
+ <type><emphasis>unspecified</emphasis></type>
+ <purpose>Meta-object describing the scope where Type is defined</purpose>
+ <description>
+ <para>A meta-object describing the scope in which the reflected type
+ is defined. Depending on where the type has been defined <code>scope</code>
+ can be either a specialization of <code><classname>meta_namespace</classname></code>
+ or a specialization of <code><classname>meta_class</classname></code>.
+ </para>
+ </description>
+ </typedef>
+ <method name="base_name">
+ <type>const <classname>bstring</classname>&amp;</type>
+ <purpose>
+ <para>This static member function returns the base name of the
+ type reflected by <code><classname>meta_type</classname></code>
+ without the nested name specifier. For example:
+ <code><classname>meta_type</classname> &lt; ::std::string &gt; :: base_name()</code>
+ returns simply <code>"string"</code>. When a full type name
+ <emphasis role="bold">with</emphasis> nested name specifier
+ is needed use the <functionname>full_name</functionname> member function
+ instead.</para>
+ </purpose>
+ <notes>
+ <para>The first call to this function can be expensive
+ for derived types like pointers, references, cv-qualified
+ types etc. because the type name needs to be properly composed from
+ the base type name, which may depending on the complexity of the type
+ lead to multiple string concatenations. Subsequent calls to this member function
+ for a concrete specialization of <classname>meta_type</classname>
+ are usually much faster.
+ </para>
+ </notes>
+ </method>
+ <method name="full_name">
+ <type>const <classname>bstring</classname>&amp;</type>
+ <purpose>
+ <para>This static member function returns the full name of the
+ type reflected by <code><classname>meta_type</classname></code>
+ with the nested name specifier. For example:
+ <code><classname>meta_type</classname> &lt; ::std::string &gt; :: full_name()</code>
+ returns <code>"::std::string"</code>. When the base type name
+ <emphasis role="bold">without</emphasis> the nested name specifier
+ is needed use the <functionname>base_name</functionname> member function
+ instead.</para>
+ </purpose>
+ <notes>
+ <para>The first call to this function can be expensive
+ for derived types like pointers, references, cv-qualified
+ types etc. because the type name needs to be properly composed from
+ the base type name, which may depending on the complexity of the type
+ lead to multiple string concatenations. Subsequent calls to this member function
+ for a concrete specialization of <classname>meta_type</classname>
+ are usually much faster.
+ </para>
+ </notes>
+ </method>
+ <method name="get_name">
+ <template>
+ <template-nontype-parameter name="FullName">
+ <type>bool</type>
+ </template-nontype-parameter>
+ </template>
+ <type>const <classname>bstring</classname>&amp;</type>
+ <parameter name="full">
+ <paramtype>::boost::mpl::bool_&lt;FullName&gt;</paramtype>
+ </parameter>
+ <purpose>
+ <para>This static member template function returns either the base name
+ <emphasis role="bold">without</emphasis> the nested name specifier
+ or the full name <emphasis role="bold">with</emphasis> the
+ nested name specifier of the type reflected by this
+ <code><classname>meta_type</classname></code>,
+ depending on the value of the template argument <code>FullName</code>.
+ For example:
+ <code><classname>meta_type</classname> &lt; ::std::string &gt; :: get_name(
+ ::boost::mpl::false_())</code> is equivalent to calling the
+ <code><functionname>base_name</functionname></code> member function and
+ returns simply <code>"string"</code> and
+ <code><classname>meta_type</classname> &lt; ::std::string &gt; :: get_name(
+ ::boost::mpl::true_())</code> is equivalent to calling the
+ <code><functionname>full_name</functionname></code> method which
+ returns <code>"::std::string"</code>.
+ </para>
+ </purpose>
+ </method>
+ </access>
+ </class>
+ </namespace><!-- mirror -->
+ </namespace><!-- boost -->
+</header>

Added: sandbox/mirror/libs/mirror/doc/samples/typenames_naive.xml
==============================================================================
--- (empty file)
+++ sandbox/mirror/libs/mirror/doc/samples/typenames_naive.xml 2008-07-12 13:57:15 EDT (Sat, 12 Jul 2008)
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+<programlisting id="mirror.motivation.sample.naivetypenames">
+#include &lt;iostream&gt;
+
+::std::ostream&amp; log = ::std::cerr;
+using ::std::endl;
+
+// a template function that returns the name
+// of the passed type
+template &lt; typename T &gt;
+const char* get_typename(void);
+
+
+template &lt; typename A, typename B, typename C &gt;
+void foo(A a, B b, C c)
+{
+ log &lt;&lt;
+ "entering foo(" &lt;&lt;
+ get_typename&lt;A&gt;() &lt;&lt;
+ ", " &lt;&lt;
+ get_typename&lt;B&gt;() &lt;&lt;
+ ", " &lt;&lt;
+ get_typename&lt;C&gt;() &lt;&lt;
+ ")" &lt;&lt;
+ endl;
+ // process args
+ log &lt;&lt;
+ "leaving foo(" &lt;&lt;
+ get_typename&lt;A&gt;() &lt;&lt;
+ ", " &lt;&lt;
+ get_typename&lt;B&gt;() &lt;&lt;
+ ", " &lt;&lt;
+ get_typename&lt;C&gt;() &lt;&lt;
+ ")" &lt;&lt;
+ endl;
+}
+
+int main(void)
+{
+ foo('A', "B", 0xC);
+ foo(0xAL, ::std::string("B"), L'C');
+ return 0;
+}
+</programlisting>
+

Added: sandbox/mirror/libs/mirror/doc/samples/typenames_naive_mirror.xml
==============================================================================
--- (empty file)
+++ sandbox/mirror/libs/mirror/doc/samples/typenames_naive_mirror.xml 2008-07-12 13:57:15 EDT (Sat, 12 Jul 2008)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+<programlisting id="mirror.motivation.sample.naivetypenames.typeid">
+#include &lt;boost/mirror/meta_type.hpp&gt;
+
+template &lt; typename T &gt;
+const char* get_typename(void)
+{
+ // The BOOST_MIRRORED_TYPE macro expands into
+ // the proper specialization of meta_type
+ // reflecting the passed type
+ return BOOST_MIRRORED_TYPE(T)::full_name().c_str();
+}
+
+</programlisting>
+

Added: sandbox/mirror/libs/mirror/doc/samples/typenames_naive_typeid.xml
==============================================================================
--- (empty file)
+++ sandbox/mirror/libs/mirror/doc/samples/typenames_naive_typeid.xml 2008-07-12 13:57:15 EDT (Sat, 12 Jul 2008)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+<programlisting id="mirror.motivation.sample.naivetypenames.typeid">
+#include &lt;typeinfo&gt;
+
+// a template function that returns the name
+// of the passed type
+template &lt; typename T &gt;
+const char* get_typename(void)
+{
+ return typeid(T).name();
+}
+
+</programlisting>
+

Modified: sandbox/mirror/libs/mirror/example/registering/types.cpp
==============================================================================
--- sandbox/mirror/libs/mirror/example/registering/types.cpp (original)
+++ sandbox/mirror/libs/mirror/example/registering/types.cpp 2008-07-12 13:57:15 EDT (Sat, 12 Jul 2008)
@@ -218,6 +218,7 @@
         // reference to function returning pointer to functions
         typedef T50& T51;
         bcout << "|51| " << BOOST_MIRRORED_TYPE(T51) ::full_name() << endl;
+ bcout << "|52| " << BOOST_MIRRORED_TYPE(T51) ::get_name(mpl::false_()) << endl;
         //
         return 0;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk