aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-03-03 15:51:56 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-03-03 15:51:56 +0200
commit2528431334b0c8aa07c85ec798be5fc9eb5b2add (patch)
tree9c5031cc98564bf72b58ccc3fdb8ecfb73c57ea2
parent31e9a014be5dd5648294a7550f18fd51da4cedc6 (diff)
Documentation updates for C++11 support
-rw-r--r--NEWS20
-rw-r--r--doc/manual.xhtml219
2 files changed, 159 insertions, 80 deletions
diff --git a/NEWS b/NEWS
index b0453dd..f2ec0fd 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,25 @@
Version 1.9.0
+ * Support for C++11. Some of the newly supported C++11 standard library
+ components include:
+ - std::unique_ptr as object pointer or value wrapper
+ - odb::lazy_unique_ptr lazy counterpart
+ - std::shared_ptr/weak_ptr as object pointer or value wrapper
+ - odb::lazy_shared_ptr/lazy_weak_ptr lazy counterparts
+ - support for array, forward_list, and unordered containers
+ - connection factory can be passed to the database constructor as
+ std::unique_ptr instead of std::auto_ptr
+
+ The ODB compiler now recognizes the --std option. Valid values for this
+ option are 'c++98' (default) and 'c++11'. In the runtime libraries the
+ C++11 support is header-only which means that the same build of a runtime
+ library can be used in both the C++98 and C++11 modes. On UNIX, the tests
+ and examples can be compiled in the C++11 mode by passing the necessary
+ options to turn the C++ compiler into this mode (e.g., -std=c++0x GCC
+ option). On Windows, the tests and examples are always built in the C++11
+ mode with VC++ 10 and later. The new 'c++11' example shows ODB support
+ for some of the C++11 features.
+
* Support for composite object ids. Now a composite value type can be used
to declare an object id member. For more information, refer to Section
7.2.1, "Composite Object Ids" in the ODB manual as well as the 'composite'
diff --git a/doc/manual.xhtml b/doc/manual.xhtml
index 92c3d9b..347c8ef 100644
--- a/doc/manual.xhtml
+++ b/doc/manual.xhtml
@@ -295,6 +295,7 @@ for consistency.
<table class="toc">
<tr><th>1.1</th><td><a href="#1.1">Architecture and Workflow</a></td></tr>
<tr><th>1.2</th><td><a href="#1.2">Benefits</a></td></tr>
+ <tr><th>1.3</th><td><a href="#1.3">Supported C++ Standards</a></td></tr>
</table>
</td>
</tr>
@@ -884,12 +885,13 @@ for consistency.
<p>In this chapter we present a high-level overview of ODB.
We will start with the ODB architecture and then outline the
workflow of building an application that uses ODB. We will
- conclude the chapter by contrasting the drawbacks of
- the traditional way of saving C++ objects to relational
- databases with the benefits of using ODB for object
- persistence. The next chapter takes a more hands-on approach
- and shows the concrete steps necessary to implement object
- persistence in a simple "Hello World" application.</p>
+ then continue by contrasting the drawbacks of the traditional
+ way of saving C++ objects to relational databases with the
+ benefits of using ODB for object persistence. We conclude the
+ chapter by discussing the C++ standards supported by ODB. The
+ next chapter takes a more hands-on approach and shows the
+ concrete steps necessary to implement object persistence in
+ a simple "Hello World" application.</p>
<h2><a name="1.1">1.1 Architecture and Workflow</a></h2>
@@ -1042,6 +1044,15 @@ for consistency.
code, is automatically generated by the ODB compiler from
these declarations.</p>
+ <h2><a name="1.3">1.3 Supported C++ Standards</a></h2>
+
+ <p>ODB provides support for ISO/IEC C++ 1998 (C++98), ISO/IEC TR 19768
+ C++ Library Extensions (C++ TR1), and ISO/IEC C++ 2011 (C++11).
+ While the majority of the examples in this manual use C++98,
+ support for the new functionality and library components introduced in
+ TR1 and C++11 are discussed throughout the document. The <code>c++11</code>
+ example in the <code>odb-examples</code> package also shows ODB
+ support for various C++11 features.</p>
<!-- CHAPTER -->
@@ -1776,7 +1787,8 @@ main (int argc, char* argv[])
made this object persistent. While here we use
<code>std::auto_ptr</code> to manage the returned object, we
could have also used another smart pointer, for example
- <code>shared_ptr</code> from TR1 or Boost. For more information
+ <code>std::unique_ptr</code> from C++11 or <code>shared_ptr</code>
+ from TR1, C++11, or Boost. For more information
on the object lifetime management and the smart pointers that we
can use for that, see <a href="#3.2">Section 3.2, "Object
and View Pointers"</a>.</p>
@@ -2279,16 +2291,18 @@ class name
or object relationships. In particular, a dynamically allocated object
or view that is returned as a raw pointer from a database operation
can be assigned to a smart pointer of our choice, for example
- <code>std::auto_ptr</code> or <code>shared_ptr</code> from TR1 or
- Boost.</p>
+ <code>std::auto_ptr</code>, <code>std::unique_ptr</code> from C++11, or
+ <code>shared_ptr</code> from TR1, C++11, or Boost.</p>
<p>However, to avoid any possibility of a mistake, such as forgetting
to use a smart pointer for a returned object or view, as well as to
simplify the use of more advanced ODB functionality, such as sessions
and bidirectional object relationships, it is recommended that you use
smart pointers with the sharing semantics as object and view pointers.
- The <code>shared_ptr</code> smart pointer from TR1 or Boost is a good
- default choice.</p>
+ The <code>shared_ptr</code> smart pointer from TR1, C++11, or Boost
+ is a good default choice. However, if sharing is not required and
+ sessions are not used, then <code>std::unique_ptr</code> or
+ <code>std::auto_ptr</code> can be used just as well.</p>
<p>ODB provides two mechanisms for changing the object or view pointer
type. We can use the <code>--default-pointer</code> option to specify
@@ -2320,7 +2334,8 @@ class person
(view)"</a> for more information on this pragma.</p>
<p>Built-in support that is provided by the ODB runtime library allows us
- to use the TR1 <code>shared_ptr</code> and <code>std::auto_ptr</code> as
+ to use <code>shared_ptr</code> (TR1 or C++11),
+ <code>std::unique_ptr</code> (C++11), or <code>std::auto_ptr</code> as
pointer types. Plus, ODB profile libraries, that are available for
commonly used frameworks and libraries (such as Boost and Qt),
provide support for smart pointers found in these frameworks and
@@ -4165,6 +4180,26 @@ namespace odb
}
</pre>
+ <p>In C++11 we can use the <code>auto</code>-typed variabe instead
+ of spelling the iterator type explicitly, for example:</p>
+
+ <pre class="c++">
+ for (auto i (r.begin ()); i != r.end (); ++i)
+ {
+ ...
+ }
+ </pre>
+
+ <p>The C++11 range-based <code>for</code>-loop can be used to further
+ simplify the iteration:</p>
+
+ <pre class="c++">
+ for (person&amp; p: r)
+ {
+ ...
+ }
+ </pre>
+
<p>The result iterator is an input iterator which means that the
only two position operations that it supports are to move to the
next object and to determine whether the end of the result stream
@@ -4295,10 +4330,14 @@ namespace odb
<h1><a name="5">5 Containers</a></h1>
<p>The ODB runtime library provides built-in persistence support for all the
- commonly used standard C++ containers, namely,
+ commonly used standard C++98 containers, namely,
<code>std::vector</code>, <code>std::list</code>, <code>std::set</code>,
<code>std::multiset</code>, <code>std::map</code>, and
- <code>std::multimap</code>. Plus, ODB profile libraries, that are
+ <code>std::multimap</code> as well as C++11 <code>std::array</code>,
+ <code>std::forward_list</code>, <code>std::unordered_set</code>,
+ <code>std::unordered_multiset</code>, <code>std::unordered_map</code>,
+ and <code>std::unordered_multimap</code>.
+ Plus, ODB profile libraries, that are
available for commonly used frameworks and libraries (such as Boost and
Qt), provide persistence support for containers found in these frameworks
and libraries (<a href="#III">Part III, "Profiles"</a>). It is also easy
@@ -4385,7 +4424,8 @@ private:
<p>In ODB an ordered container is any container that maintains (explicitly
or implicitly) an order of its elements in the form of an integer index.
Standard C++ containers that are ordered include <code>std::vector</code>
- and <code>std::list</code>. While elements in <code>std::set</code>
+ and <code>std::list</code> as well as C++11 <code>std::array</code> and
+ <code>std::forward_list</code>. While elements in <code>std::set</code>
are also kept in a specific order, this order is not based on an
integer index but rather on the relationship between elements. As
a result, <code>std::set</code> is not considered an ordered
@@ -4479,7 +4519,9 @@ private:
or may not guarantee a particular order of the elements that
it stores. Standard C++ containers that are considered set
containers for the purpose of persistence include
- <code>std::set</code> and <code>std::multiset</code>.</p>
+ <code>std::set</code> and <code>std::multiset</code> as well
+ as C++11 <code>std::unordered_set</code> and
+ <code>std::unordered_multiset</code>.</p>
<p>The database table for a set container consists of at least
two columns. The first column contains the object id of a
@@ -4539,7 +4581,9 @@ private:
may or may not guarantee a particular order of the elements that
it stores. Standard C++ containers that are considered map
containers for the purpose of persistence include
- <code>std::map</code> and <code>std::multimap</code>.</p>
+ <code>std::map</code> and <code>std::multimap</code> as well
+ as C++11 <code>std::unordered_map</code> and
+ <code>std::unordered_multimap</code>.</p>
<p>The database table for a map container consists of at least
three columns. The first column contains the object id of a
@@ -4643,7 +4687,8 @@ private:
<p>Relationships between persistent objects are expressed with pointers or
containers of pointers. The ODB runtime library provides built-in support
- for the TR1 <code>shared_ptr</code>/<code>weak_ptr</code>,
+ for <code>shared_ptr</code>/<code>weak_ptr</code> (TR1 or C++11),
+ <code>std::unique_ptr</code> (C++11),
<code>std::auto_ptr</code>, and raw pointers. Plus, ODB profile
libraries, that available for commonly used frameworks and libraries
(such as Boost and Qt), provide support for smart pointers found in these
@@ -5385,13 +5430,20 @@ t.commit ();
access it.</p>
<p>The ODB runtime library provides lazy counterparts for all the
- supported pointers, namely: <code>odb::lazy_shared_ptr</code> and
- <code>odb::lazy_weak_ptr</code> for TR1 <code>shared_ptr</code> and
- <code>weak_ptr</code>, <code>odb::lazy_auto_ptr</code> for
- <code>std::auto_ptr</code>, and <code>odb::lazy_ptr</code> for raw
- pointers. The ODB profile libraries provide lazy pointer
- implementations for smart pointers from popular frameworks and
- libraries (<a href="#III">Part III, "Profiles"</a>).</p>
+ supported pointers, namely:
+ <code>odb::lazy_shared_ptr</code>/<code>lazy_weak_ptr</code>
+ for C++11 <code>std::shared_ptr</code>/<code>weak_ptr</code>,
+ <code>odb::tr1::lazy_shared_ptr</code>/<code>lazy_weak_ptr</code>
+ for TR1 <code>std::tr1::shared_ptr</code>/<code>weak_ptr</code>,
+ <code>odb::lazy_unique_ptr</code> for C++11 <code>std::unique_ptr</code>,
+ <code>odb::lazy_auto_ptr</code> for <code>std::auto_ptr</code>,
+ and <code>odb::lazy_ptr</code> for raw pointers. The TR1 lazy
+ pointers are defined in the <code>&lt;odb/tr1/lazy-ptr.hxx></code>
+ header while all the others &mdash; in
+ <code>&lt;odb/lazy-ptr.hxx></code>. The ODB profile
+ libraries also provide lazy pointer implementations for smart pointers
+ from popular frameworks and libraries (<a href="#III">Part III,
+ "Profiles"</a>).</p>
<p>While we will discuss the interface of lazy pointers in more detail
shortly, the most commonly used extra function provided by these
@@ -5507,6 +5559,7 @@ public:
// Query object id and database of a persistent object.
//
template &lt;class O /* = T */>
+ // C++11: template &lt;class O = T>
object_traits&lt;O>::id_type object_id () const;
odb::database&amp; database () const;
@@ -5536,6 +5589,7 @@ for (employees::iterator i (es.begin ()); i != es.end (); ++i)
lazy_weak_ptr&lt;employee>&amp; lwp (*i);
if (lwp.object_id&lt;employee> () &lt; 100)
+ // C++11: if (lwp.object_id () &lt; 100)
{
shared_ptr&lt;employee> e (lwp.load ()); // Load and lock.
cout &lt;&lt; e->first_ &lt;&lt; " " &lt;&lt; e->last_ &lt;&lt; endl;
@@ -6240,8 +6294,9 @@ class person
</pre>
<p>The ODB compiler includes built-in support for using
- <code>std::auto_ptr</code> and <code>std::tr1::shared_ptr</code>
- as pointers to values. Plus, ODB profile libraries, that are
+ <code>std::auto_ptr</code>, <code>std::unique_ptr</code> (C++11),
+ and <code>shared_ptr</code> (TR1 or C++11) as pointers to values.
+ Plus, ODB profile libraries, that are
available for commonly used frameworks and libraries (such as Boost and
Qt), provide support for smart pointers found in these frameworks
and libraries (<a href="#III">Part III, "Profiles"</a>).</p>
@@ -7717,14 +7772,14 @@ t.commit ();
<p>The per-object caching policies depend on the object pointer kind
(<a href="#6.4">Section 6.4, "Using Custom Smart Pointers"</a>).
- Objects with a unique pointer, such as <code>std::auto_ptr</code>,
- as an object pointer are never cached since it is not possible to have
- two such pointers pointing to the same object. When an object is
- persisted via a pointer or loaded as a dynamically allocated instance,
- objects with both raw and shared pointers as object pointers are
- cached. If an object is persisted as a reference or loaded into
- a pre-allocated instance, the object is only cached if its object
- pointer is a raw pointer.</p>
+ Objects with a unique pointer, such as <code>std::auto_ptr</code>
+ or <code>std::unique_ptr</code>, as an object pointer are never
+ cached since it is not possible to have two such pointers pointing
+ to the same object. When an object is persisted via a pointer or
+ loaded as a dynamically allocated instance, objects with both raw
+ and shared pointers as object pointers are cached. If an object is
+ persisted as a reference or loaded into a pre-allocated instance,
+ the object is only cached if its object pointer is a raw pointer.</p>
<p>Also note that when we persist an object as a constant reference
or constant pointer, the session caches such an object as
@@ -11042,7 +11097,7 @@ namespace odb
const char* socket = 0,
const char* charset = 0,
unsigned long client_flags = 0,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
database (const std::string&amp; user,
const std::string&amp; passwd,
@@ -11052,7 +11107,7 @@ namespace odb
const std::string* socket = 0,
const std::string&amp; charset = "",
unsigned long client_flags = 0,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
database (const std::string&amp; user,
const std::string* passwd,
@@ -11062,7 +11117,7 @@ namespace odb
const std::string* socket = 0,
const std::string&amp; charset = "",
unsigned long client_flags = 0,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
database (const std::string&amp; user,
const std::string&amp; passwd,
@@ -11072,7 +11127,7 @@ namespace odb
const std::string&amp; socket,
const std::string&amp; charset = "",
unsigned long client_flags = 0,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
database (const std::string&amp; user,
const std::string* passwd,
@@ -11082,14 +11137,14 @@ namespace odb
const std::string&amp; socket,
const std::string&amp; charset = "",
unsigned long client_flags = 0,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
database (int&amp; argc,
char* argv[],
bool erase = false,
const std::string&amp; charset = "",
unsigned long client_flags = 0,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
static void
print_usage (std::ostream&amp;);
@@ -11188,12 +11243,12 @@ namespace odb
<p>The static <code>print_usage()</code> function prints the list of options
with short descriptions that are recognized by this constructor.</p>
- <p>The last argument to all of the constructors is a
- pointer to the connection factory. If we pass a
- non-<code>NULL</code> value, the database instance assumes
- ownership of the factory instance. The connection factory
- interface as well as the available implementations are described
- in the next section.</p>
+ <p>The last argument to all of the constructors is a pointer to the
+ connection factory. In C++98, it is <code>std::auto_ptr</code> while
+ in C++11 <code>std::unique_ptr</code> is used instead. If we pass a
+ non-<code>NULL</code> value, the database instance assumes ownership
+ of the factory instance. The connection factory interface as well as
+ the available implementations are described in the next section.</p>
<p>The set of accessor functions following the constructors allows us
to query the parameters of the <code>database</code> instance.</p>
@@ -11650,14 +11705,14 @@ namespace odb
database (const std::string&amp; name,
int flags = SQLITE_OPEN_READWRITE,
bool foreign_keys = true,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
database (int&amp; argc,
char* argv[],
bool erase = false,
int flags = SQLITE_OPEN_READWRITE,
bool foreign_keys = true,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
static void
print_usage (std::ostream&amp;);
@@ -11751,11 +11806,12 @@ auto_ptr&lt;odb::database> db (
<p>The static <code>print_usage()</code> function prints the list of options
with short descriptions that are recognized by the second constructor.</p>
- <p>The last argument to both constructors is a pointer to the connection
- factory. If we pass a non-<code>NULL</code> value, the database instance
- assumes ownership of the factory instance. The connection factory
- interface as well as the available implementations are described
- in the next section.</p>
+ <p>The last argument to all of the constructors is a pointer to the
+ connection factory. In C++98, it is <code>std::auto_ptr</code> while
+ in C++11 <code>std::unique_ptr</code> is used instead. If we pass a
+ non-<code>NULL</code> value, the database instance assumes ownership
+ of the factory instance. The connection factory interface as well as
+ the available implementations are described in the next section.</p>
<p>The set of accessor functions following the constructors allows us
to query the parameters of the <code>database</code> instance.</p>
@@ -12405,7 +12461,7 @@ namespace odb
const std::string&amp; host = "",
unsigned int port = 0,
const std::string&amp; extra_conninfo = "",
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
database (const std::string&amp; user,
const std::string&amp; password,
@@ -12413,16 +12469,16 @@ namespace odb
const std::string&amp; host = "",
const std::string&amp; socket_ext = "",
const std::string&amp; extra_conninfo = "",
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
database (const std::string&amp; conninfo,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
database (int&amp; argc,
char* argv[],
bool erase = false,
const std::string&amp; extra_conninfo = "",
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
static void
print_usage (std::ostream&amp;);
@@ -12514,10 +12570,11 @@ namespace odb
with short descriptions that are recognized by this constructor.</p>
<p>The last argument to all of the constructors is a pointer to the
- connection factory. If we pass a non-<code>NULL</code> value, the
- database instance assumes ownership of the factory instance. The
- connection factory interface as well as the available implementations
- are described in the next section.</p>
+ connection factory. In C++98, it is <code>std::auto_ptr</code> while
+ in C++11 <code>std::unique_ptr</code> is used instead. If we pass a
+ non-<code>NULL</code> value, the database instance assumes ownership
+ of the factory instance. The connection factory interface as well as
+ the available implementations are described in the next section.</p>
<p>The set of accessor functions following the constructors allows us
to query the parameters of the <code>database</code> instance. Note that
@@ -13033,7 +13090,7 @@ namespace odb
ub2 charset = 0,
ub2 ncharset = 0,
OCIEnv* environment = 0,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
database (const std::string&amp; user,
const std::string&amp; password,
@@ -13043,7 +13100,7 @@ namespace odb
ub2 charset = 0,
ub2 ncharset = 0,
OCIEnv* environment = 0,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
database (int&amp; argc,
char* argv[],
@@ -13051,7 +13108,7 @@ namespace odb
ub2 charset = 0,
ub2 ncharset = 0,
OCIEnv* environment = 0,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
static void
print_usage (std::ostream&amp;);
@@ -13174,11 +13231,12 @@ namespace odb
environment handle is used, then the <code>charset</code> and
<code>ncharset</code> arguments have no effect.</p>
- <p>The last argument to all of the constructors is a pointer to a
- connection factory. If we pass a non-<code>NULL</code> value, the
- database instance assumes ownership of the factory instance. The
- connection factory interface as well as the available implementations
- are described in the next section.</p>
+ <p>The last argument to all of the constructors is a pointer to the
+ connection factory. In C++98, it is <code>std::auto_ptr</code> while
+ in C++11 <code>std::unique_ptr</code> is used instead. If we pass a
+ non-<code>NULL</code> value, the database instance assumes ownership
+ of the factory instance. The connection factory interface as well as
+ the available implementations are described in the next section.</p>
<p>The set of accessor functions following the constructors allows us
to query the parameters of the <code>database</code> instance.</p>
@@ -13896,7 +13954,7 @@ namespace odb
const std::string&amp; driver = "",
const std::string&amp; extra_connect_string = "",
SQLHENV environment = 0,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
database (const std::string&amp; user,
const std::string&amp; password,
@@ -13907,7 +13965,7 @@ namespace odb
const std::string&amp; driver = "",
const std::string&amp; extra_connect_string = "",
SQLHENV environment = 0,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
database (const std::string&amp; user,
const std::string&amp; password,
@@ -13917,18 +13975,18 @@ namespace odb
const std::string&amp; driver = "",
const std::string&amp; extra_connect_string = "",
SQLHENV environment = 0,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
database (const std::string&amp; connect_string,
SQLHENV environment = 0,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
database (int&amp; argc,
char* argv[],
bool erase = false,
const std::string&amp; extra_connect_string = "",
SQLHENV environment = 0,
- std::auto_ptr&lt;connection_factory> = 0);
+ std::[auto|unique]_ptr&lt;connection_factory> = 0);
static void
print_usage (std::ostream&amp;);
@@ -14158,11 +14216,12 @@ odb::mssql::database dbA ("test",
handle should be valid for the lifetime of the <code>database</code>
instance.</p>
- <p>The last argument to all of the constructors is a pointer to a
- connection factory. If we pass a non-<code>NULL</code> value, the
- database instance assumes ownership of the factory instance. The
- connection factory interface as well as the available implementations
- are described in the next section.</p>
+ <p>The last argument to all of the constructors is a pointer to the
+ connection factory. In C++98, it is <code>std::auto_ptr</code> while
+ in C++11 <code>std::unique_ptr</code> is used instead. If we pass a
+ non-<code>NULL</code> value, the database instance assumes ownership
+ of the factory instance. The connection factory interface as well as
+ the available implementations are described in the next section.</p>
<p>The set of accessor functions following the constructors allows us
to query the parameters of the <code>database</code> instance.</p>