extended_type_info.html 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. <!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html>
  3. <!--
  4. (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
  5. Use, modification and distribution is subject to the Boost Software
  6. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7. http://www.boost.org/LICENSE_1_0.txt)
  8. -->
  9. <head>
  10. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  11. <link rel="stylesheet" type="text/css" href="../../../boost.css">
  12. <link rel="stylesheet" type="text/css" href="style.css">
  13. <title>Serialization - extended_type_info</title>
  14. </head>
  15. <body link="#0000ff" vlink="#800080">
  16. <table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
  17. <tr>
  18. <td valign="top" width="300">
  19. <h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
  20. </td>
  21. <td valign="top">
  22. <h1 align="center">Serialization</h1>
  23. <h2 align="center"><code style="white-space: normal">extended_type_info</code></h2>
  24. </td>
  25. </tr>
  26. </table>
  27. <hr>
  28. <dl class="page-index">
  29. <dt><a href="#motivation">Motivation</a>
  30. <dt><a href="#runtime">Runtime Interface</a>
  31. <dt><a href="#requirements">Requirements</a>
  32. <dt><a href="#models">Models</a>
  33. <dt><a href="#example">Example</a>
  34. </dl>
  35. <h3><a name="motivation">Motivation</a></h3>
  36. The serialization library needs a system like
  37. <code style="white-space: normal">type_info/typeid()</code> to perform
  38. the following functions
  39. <ol>
  40. <li>
  41. given a pointer to a type T discover the true type pointed to.
  42. <li>
  43. given an "external" key - determine what type of object to create.
  44. </ol>
  45. <h3>The problem with <code style="white-space: normal">std::type_info</code></h3>
  46. <ul>
  47. <li>
  48. The main function we require - <code style="white-space: normal">std::typeid()</code>
  49. is not available in all environments. Support for this function depends upon
  50. runtime typing(RTTI) support from the compiler. This may be non-existent
  51. or not enabled for reasons such as a percieved inefficiency.
  52. <li>
  53. <code style="white-space: normal">std::type_info</code> includes a string
  54. containing type name. This would seem to satisfy 2) above.
  55. But the format of this string is not consistent accross compilers, libraries,
  56. and operating systems. This makes it unusable for support of portable archives.
  57. <li>
  58. Even if the type name string could somehow be made portable, there is no
  59. guarantee that class headers would be included in the same namespace accross
  60. different applications. In fact, including different headers in different
  61. namespaces is an accepted method used to avoid namespace conflicts.
  62. Thus the namespace::class_name can't be used as a key.
  63. <li>
  64. There exists the possibility that different classes use different type id
  65. mechanisms. The class header might include this information. If we want to
  66. import class headers accross applications, it's convenient that the type id
  67. mechanism support inter-operability accross different type id systems.
  68. </ul>
  69. <h3>Features</h3>
  70. <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
  71. extended_type_info</a></code> is an implementation
  72. of <code style="white-space: normal">std::type_info</code> functionality with the
  73. following features:
  74. <ul>
  75. <li>
  76. Builds a set of <a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
  77. <code style="white-space: normal">extended_type_info</a></code> records - one for each type
  78. serialized.
  79. <li>
  80. permits association of an arbitrary string key with a type. Often this key would
  81. be the class name - but it doesn't have to be. This key is referred to as
  82. a GUID - Globally Unique IDentifier. Presumably it should be unique in the universe.
  83. Typically this GUID would be in header files and be used to match type accross
  84. applications. The macro BOOST_CLASS_EXPORT can be invoked to associate a string
  85. key with any known type. We'll refer to these types as "exported types"
  86. <li>
  87. permits the "mixing" of type info systems. For example, one class might use
  88. <code style="white-space: normal">typeid()</code> to find the external identifier
  89. of a class while another might not.
  90. </ul>
  91. Exported types are maintained in a global table so that given a string key, the
  92. corresponding type can be found. This facility is used by the serialization library
  93. in order to construct types serialized through a base class pointer.
  94. <h3><a name="runtime">Runtime Interface</a></h3>
  95. <pre><code">
  96. namespace boost {
  97. namespace serialization {
  98. class extended_type_info
  99. {
  100. protected:
  101. // this class can't be used as is. It's just the
  102. // common functionality for all type_info replacement
  103. // systems. Hence, make these protected
  104. extended_type_info(
  105. const unsigned int type_info_key,
  106. const char * key
  107. );
  108. ~extended_type_info();
  109. void key_register();
  110. void key_unregister();
  111. public:
  112. const char * get_key() const;
  113. bool operator<(const extended_type_info &rhs) const;
  114. bool operator==(const extended_type_info &rhs) const;
  115. bool operator!=(const extended_type_info &rhs) const {
  116. return !(operator==(rhs));
  117. }
  118. // for plugins
  119. virtual void * construct(unsigned int count = 0, ...) const;
  120. virtual void destroy(void const * const p) const;
  121. static const extended_type_info * find(const char *key);
  122. };
  123. } // namespace serialization
  124. } // namespace boost
  125. </code></pre>
  126. <p>
  127. Generally, there will be one and only one
  128. <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
  129. instance created for each type. However, this is enforced only at the executable
  130. module level. That is, if a program includes some shared libraries or DLLS,
  131. there may be more than one instance of this class correponding to a particular type.
  132. For this reason the comparison functions below can't just compare the addresses of
  133. this instance but rather must be programmed to compare the actual information
  134. the instances contain.
  135. <dl>
  136. <dt><h4><pre><code>
  137. extended_type_info(unsigned int type_info_key, const char *key);
  138. </code></pre></h4></dt>
  139. <dd>
  140. This constructor should be called by all derived classes.
  141. The first argument should be the particular implementation.
  142. For this default implementation base on typeid(), this is the
  143. value 1. Each system must have its own integer. This value
  144. is used to permit the inter-operability of different typeinfo
  145. systems.
  146. <p>
  147. The second argument is a const string which is the external
  148. name of the type to which this record corresponds.
  149. It may sometimes be referred to as a GUID - a <b>G</b>lobal <b>U</b>nique <b>ID</b>entifier.
  150. It is passed through archives from one program invocation to
  151. another to uniquely identify the types that the archive contains.
  152. If the "export" facility is not going to be used,
  153. this value may be NULL.
  154. </dd>
  155. <dt><h4><pre><code>
  156. void key_register();
  157. void key_unregister();
  158. </code></pre></h4></dt>
  159. <dd>
  160. This system maintains a global table which relates
  161. external strings to
  162. <code style="white-space: normal">extended_type_info</code> records.
  163. This table is used when loading pointers to objects serialized
  164. through a base class pointer. In this case, the archive
  165. contains a string which is looked up in this table to
  166. determine which <code style="white-space: normal">extended_type_info</code>
  167. to use for creating a new object.
  168. <p>
  169. These functions are called by constructors and
  170. destructors of classes which implement
  171. <code style="white-space: normal">extended_type_info</code>
  172. to add and remove entries from this table.
  173. </dd>
  174. <dt><h4><pre><code>
  175. const char *get_key() const;
  176. </code></pre></h4></dt>
  177. <dd>
  178. Retrieves the key for <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
  179. instance. If no key has been associated with the instance, then a NULL is returned.
  180. </dd>
  181. <dt><h4><pre><code>
  182. bool operator<(const extended_type_info & rhs) const;
  183. bool operator==(const extended_type_info & rhs) const;
  184. bool operator!=(const extended_type_info & rhs) const;
  185. </code></pre></h4></dt>
  186. <dd>
  187. These functions are used to compare
  188. <a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
  189. <code style="white-space: normal">
  190. extended_type_info
  191. </code>
  192. </a>
  193. objects. They impose a strict total ordering on all
  194. <code style="white-space: normal">extended_type_info</code> records.
  195. </dd>
  196. <dt><h4><pre><code>
  197. virtual void * construct(unsigned int count = 0, ...) const;
  198. </code></pre></h4></dt>
  199. <dd>
  200. Construct a new instance of the type to which this
  201. <a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
  202. <code style="white-space: normal">
  203. extended_type_info
  204. </code>
  205. </a>
  206. record corresponds. This function takes a variable list of up to 4 arguments
  207. of any type. These arguments are passed to the type's constructor
  208. at runtime. In order to use the facility,
  209. one must declare a type sequence for the constructor arguments.
  210. Arguments for this function must match in number and type
  211. with those specified when the type was exported.
  212. This function permits one to create instances of
  213. any exported type given only the exported <strong>GUID</strong> assigned
  214. with BOOST_CLASS_EXPORT.
  215. If these types are defined in DLLS or shared libraries loaded at runtime,
  216. these constructors can be called until the module is unloaded.
  217. Such modules are referred to as <b>plugins</b>.
  218. </code>
  219. </dd>
  220. <dt><h4><pre><code>
  221. virtual void destroy(void const * const p) const;
  222. </code></pre></h4></dt>
  223. <dd>
  224. Destroy an instance created by the above constructor.
  225. </dd>
  226. <dt><h4><pre><code>
  227. static const extended_type_info * find(const char *key);
  228. </code></pre></h4></dt>
  229. <dd>
  230. Given a character string key or <strong>GUID</strong>, return the address of a
  231. corresponding <code style="white-space: normal"><a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
  232. object.
  233. </dl>
  234. <h3><a name="requirements">Requirements for an Implementation</a></h3>
  235. In order to be used by the serialization library, an implementation of
  236. <code style="white-space: normal">extended_type_info</code>,
  237. (referred to as ETI here), must be derived from
  238. <a target="extended_type_info.hpp" href = "../../../boost/serialization/extended_type_info.hpp">
  239. <code style="white-space: normal">
  240. extended_type_info
  241. </code>
  242. </a>
  243. and also implement the following:
  244. <dl>
  245. <dt><h4><code style="white-space: normal"><pre>
  246. template&lt;class ETI&gt;
  247. const extended_type_info *
  248. ETI::get_derived_extended_type_info(const T & t) const;
  249. </pre></code></h4></dt>
  250. <dd>
  251. Return a pointer to the
  252. <code style="white-space: normal">extended_type_info</code>
  253. instance that corresponds to
  254. the "true type" of the type T. The "true type" is the lowest type in the
  255. hierarchy of classes. The type T can always be cast to the "true type" with
  256. a static cast. Implementation of this function will vary among type id systems
  257. and sometimes will make presumptions about the type T than can be identified
  258. with a particular <code style="white-space: normal">extended_type_info</code> implementation.
  259. </dd>
  260. <dt><h4><code style="white-space: normal"><pre>
  261. virtual bool ETI::is_less_than(const extended_type_info &rhs) const;
  262. </pre></code></h4></dt>
  263. <dd>
  264. Compare this instance to another one using the same
  265. <code style="white-space: normal">extended_type_info</code> implementation.
  266. </dd>
  267. <dt><h4><code style="white-space: normal"><pre>
  268. virtual bool ETI::is_equal(const extended_type_info &rhs) const;
  269. </pre></code></h4></dt>
  270. <dd>
  271. Compare this instance to another one using the same
  272. <code style="white-space: normal">extended_type_info</code> implementation.
  273. Return <code style="white-space: normal">true</code> if the types referred
  274. to are the same. Otherwise return
  275. <code style="white-space: normal">false</code>
  276. </dd>
  277. <dt><h4><code style="white-space: normal"><pre>
  278. const char ETI::get_key() const;
  279. </pre></code></h4></dt>
  280. <dd>
  281. Retrieve the external key (aka GUID) for this class.
  282. </dd>
  283. <dt><h4><code style="white-space: normal"><pre>
  284. virtual void * construct(unsigned int count, ...) const;
  285. </pre></code></h4></dt>
  286. <dd>
  287. Construct an instance of the corresponding type
  288. with the include argument list.
  289. </dd>
  290. <dt><h4><code style="white-space: normal"><pre>
  291. virtual void * destroy(void const * const ptr ) const;
  292. </pre></code></h4></dt>
  293. <dd>
  294. Destroy an instance of this type. This calls the
  295. proper destructor and recovers allocated memory.
  296. </dd>
  297. </dl>
  298. <h3><a name="models">Models</a></h3>
  299. The serialization library includes two distinct
  300. <code style="white-space: normal"><a target="extended_type_info.hpp" href="../../../boost/serialization/extended_type_info.hpp">extended_type_info</a></code>
  301. implementations.
  302. <p>
  303. <code style="white-space: normal"><h4><a target="extended_type_info_typeid.hpp" href = "../../../boost/serialization/extended_type_info_typeid.hpp">
  304. extended_type_info_typeid</a></h4></code>is implemented in terms of the standard typeid(). It presumes that RTTI support is enabled
  305. by the compiler.
  306. <p>
  307. <code style="white-space: normal"><h4><a target="extended_type_info_no_rtti.hpp" href="../../../boost/serialization/extended_type_info_no_rtti.hpp">
  308. extended_type_info_no_rtti</a></h4></code>
  309. is implemented in a way that doesn't rely on the existence RTTI.
  310. Instead, it requires that all polymorphic types be explictly exported.
  311. In addition, if the export facility is to be used to serialize types
  312. through base class pointers, those types are required to implement
  313. a virtual function with the signature:
  314. <code><pre>
  315. virtual const char * get_key();
  316. </pre></code>
  317. which returns a unique string the most derived object this class.
  318. This function must be virtual in order to implement the functionality required by
  319. <code style="white-space: normal">ETI::get_derived_extended_type_info</code>
  320. as described above.
  321. <h3><a name="example">Example</a></h3>
  322. The test program <code style="white-space: normal"><a target="test_no_rtti" href="../test/test_no_rtti.cpp">test_no_rtti</a></code>
  323. implements this function in terms of the <code style="white-space: normal"><a target="extended_type_info_no_rtti.hpp" href="../../../boost/serialization/extended_type_info_no_rtti.hpp">
  324. extended_type_info</a></code> API above to return the export key associated with the class.
  325. This requires that non-abstract types be exported. It also demonstrates the
  326. inter-operability between two different implementations of
  327. <code style="white-space: normal">extended_type_info</code>.
  328. <h3><a name="type_requirements">Requirements for Each Type</a></h3>
  329. Each type to be managed by the system must be
  330. "registered" individually. This is accomplished by instantiating
  331. templates. For example, if the type T is to use the type_info system
  332. one would include the following code:
  333. <code style="white-space: normal"><pre>
  334. namespace boost {
  335. namespace serialization {
  336. template
  337. struct extended_type_info_typeid&gt;T&gt;;
  338. template
  339. struct extended_type_info_typeid&gt;const T&gt;;
  340. } // serialization
  341. } // boost
  342. </pre></code>
  343. For those using the serialization library, this step can be skipped
  344. as it is done automatically. The serialization library includes
  345. the macro:
  346. <code style="white-space: normal"><pre>
  347. BOOST_CLASS_TYPE_INFO(
  348. my_type,
  349. extended_type_info_typeid&gt;my_class&gt;
  350. )
  351. </pre></code>
  352. which is used to specify which <code>extended_type_info</code> system is to
  353. be used for a given type.
  354. <p>
  355. <code>extended_type_info</code> includes a facility for constructing
  356. instances of types without knowing what the exact types are. This is done
  357. with the function
  358. <code>
  359. virtual void * extended_type_info::construct(unsigned int count = 0, ...) const;
  360. </code>
  361. . For example:
  362. <br>
  363. <code><pre>
  364. struct base {
  365. ...
  366. };
  367. struct derived : public base {
  368. ...
  369. };
  370. ...
  371. extended_type_info *eti = extended_type_info::find("my_class")
  372. base * b = eti->construct(...);
  373. </pre></code>
  374. <br>
  375. The <code>construct</code> takes an argument count and up to
  376. four parameters of any type. The arguments are passed to the
  377. constructor of "my_class".
  378. A complete example of this can be found
  379. <a target="test_dll_plugin.cpp" href="../test/test_dll_plugin.cpp">here</a>
  380. <hr>
  381. <p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2005-2009.
  382. Distributed under the Boost Software License, Version 1.0. (See
  383. accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  384. </i></p>
  385. </body>
  386. </html>