summaryrefslogtreecommitdiff
path: root/odb
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-11-16 08:49:35 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-11-16 08:49:35 +0200
commit302b804ec633889f26dc54d937d9becc09246152 (patch)
tree730c672f1cbeb89d9be85bbf53c7f2f3f0bd9486 /odb
parent89a3b6133ade1ccb3a8e9ab9c86eac6aaef5db69 (diff)
Rework pointer traits, add naked, auto_ptr, and TR1 specializations
Diffstat (limited to 'odb')
-rw-r--r--odb/header.cxx20
-rw-r--r--odb/mysql/source.cxx2
-rw-r--r--odb/odb.cxx7
-rw-r--r--odb/tracer/source.cxx2
-rw-r--r--odb/type-processor.cxx136
5 files changed, 135 insertions, 32 deletions
diff --git a/odb/header.cxx b/odb/header.cxx
index 35a95ab..d7fed95 100644
--- a/odb/header.cxx
+++ b/odb/header.cxx
@@ -87,6 +87,26 @@ generate_header (context& ctx)
<< "#include <odb/traits.hxx>" << endl
<< endl;
+ // In case of a boost TR1 implementation, we cannot distinguish
+ // between the boost::shared_ptr and std::tr1::shared_ptr usage since
+ // the latter is just a using-declaration for the former. To resolve
+ // this we will include TR1 traits if the Boost TR1 header is included.
+ //
+ if (ctx.unit.count ("tr1-pointer-used") &&
+ ctx.unit.get<bool> ("tr1-pointer-used"))
+ {
+ ctx.os << "#include <odb/tr1-pointer-traits.hxx>" << endl
+ << endl;
+ }
+ else if (ctx.unit.count ("boost-pointer-used") &&
+ ctx.unit.get<bool> ("boost-pointer-used"))
+ {
+ ctx.os << "#ifdef BOOST_TR1_MEMORY_HPP_INCLUDED" << endl
+ << "# include <odb/tr1-pointer-traits.hxx>" << endl
+ << "#endif" << endl
+ << endl;
+ }
+
/*
traversal::unit unit;
traversal::defines unit_defines;
diff --git a/odb/mysql/source.cxx b/odb/mysql/source.cxx
index 2e54a04..2f65de6 100644
--- a/odb/mysql/source.cxx
+++ b/odb/mysql/source.cxx
@@ -2176,7 +2176,7 @@ namespace mysql
<< "{"
<< "pointer_type p (access::object_factory< object_type, " <<
"pointer_type >::create ());"
- << "pointer_traits< pointer_type >::guard g (p);"
+ << "pointer_traits< pointer_type >::guard_type g (p);"
<< "object_type& obj (pointer_traits< pointer_type >::get_ref (p));"
<< "init (obj, sts.image ());";
diff --git a/odb/odb.cxx b/odb/odb.cxx
index a1beccf..075cf53 100644
--- a/odb/odb.cxx
+++ b/odb/odb.cxx
@@ -530,7 +530,12 @@ main (int argc, char* argv[])
<< "# include <tr1/memory>" << endl
<< "#endif" << endl;
- // Standard containers traits.
+ // Standard pointer traits.
+ //
+ os << "#include <odb/pointer-traits.hxx>" << endl
+ << "#include <odb/tr1-pointer-traits.hxx>" << endl;
+
+ // Standard container traits.
//
os << "#include <odb/container-traits.hxx>" << endl;
}
diff --git a/odb/tracer/source.cxx b/odb/tracer/source.cxx
index 8d1bd4f..b77d69a 100644
--- a/odb/tracer/source.cxx
+++ b/odb/tracer/source.cxx
@@ -95,7 +95,7 @@ namespace tracer
<< endl
<< "pointer_type r (access::object_factory< object_type, " <<
"pointer_type >::create ());"
- << "pointer_traits< pointer_type >::guard g (r);"
+ << "pointer_traits< pointer_type >::guard_type g (r);"
<< "r->" << id.name () << " = id;"
<< "g.release ();"
<< "return r;"
diff --git a/odb/type-processor.cxx b/odb/type-processor.cxx
index b99cfb9..921a90b 100644
--- a/odb/type-processor.cxx
+++ b/odb/type-processor.cxx
@@ -399,10 +399,26 @@ namespace
// Assign object pointer.
//
if (obj)
+ assign_pointer (c);
+ }
+
+ void
+ assign_pointer (type& c)
+ {
+ try
{
string ptr;
string const& name (c.fq_name ());
+ if (!unit.count ("tr1-pointer-used"))
+ {
+ unit.set ("tr1-pointer-used", false);
+ unit.set ("boost-pointer-used", false);
+ }
+
+ bool& tr1 (unit.get<bool> ("tr1-pointer-used"));
+ bool& boost (unit.get<bool> ("boost-pointer-used"));
+
if (c.count ("pointer"))
{
string const& p (c.get<string> ("pointer"));
@@ -412,44 +428,66 @@ namespace
else if (p[p.size () - 1] == '*')
ptr = p;
else if (p.find ('<') != string::npos)
+ {
+ // Template-id. See if it is from TR1.
+ //
ptr = p;
+ tr1 = tr1
+ || p.compare (0, 8, "std::tr1") == 0
+ || p.compare (0, 10, "::std::tr1") == 0;
+ }
else
{
// This is not a template-id. Resolve it and see if it is a
// template or a type.
//
- try
+ tree decl (resolve_type (p, c.scope ()));
+ int tc (TREE_CODE (decl));
+
+ if (tc == TYPE_DECL)
{
- tree t (resolve_type (p, c.scope ()));
- int tc (TREE_CODE (t));
-
- if (tc == TYPE_DECL)
- ptr = p;
- else if (tc == TEMPLATE_DECL && DECL_CLASS_TEMPLATE_P (t))
- ptr = p + "< " + name + " >";
- else
- {
- cerr << c.file () << ":" << c.line () << ":" << c.column ()
- << ": error: name '" << p << "' specified with "
- << "'#pragma object pointer' does not name a type "
- << "or a template" << endl;
+ ptr = p;
- throw generation_failed ();
+ // This can be a typedef'ed alias for a TR1 template-id.
+ //
+ if (tree ti = TYPE_TEMPLATE_INFO (TREE_TYPE (decl)))
+ {
+ tree t (TI_TEMPLATE (ti)); // DECL_TEMPLATE
+
+ // Get to the most general template declaration.
+ //
+ while (DECL_TEMPLATE_INFO (t))
+ t = DECL_TI_TEMPLATE (t);
+
+ string n (decl_as_string (t, TFF_PLAIN_IDENTIFIER));
+
+ // In case of a boost TR1 implementation, we cannot
+ // distinguish between the boost:: and std::tr1::
+ // usage since the latter is just a using-declaration
+ // for the former.
+ //
+ tr1 = tr1
+ || n.compare (0, 8, "std::tr1") == 0
+ || n.compare (0, 10, "::std::tr1") == 0;
+
+ boost = boost
+ || n.compare (0, 17, "boost::shared_ptr") == 0
+ || n.compare (0, 19, "::boost::shared_ptr") == 0;
}
}
- catch (invalid_name const&)
+ else if (tc == TEMPLATE_DECL && DECL_CLASS_TEMPLATE_P (decl))
{
- cerr << c.file () << ":" << c.line () << ":" << c.column ()
- << ": error: type name '" << p << "' specified with "
- << "'#pragma object pointer' is invalid" << endl;
-
- throw generation_failed ();
+ ptr = p + "< " + name + " >";
+ tr1 = tr1
+ || p.compare (0, 8, "std::tr1") == 0
+ || p.compare (0, 10, "::std::tr1") == 0;
}
- catch (unable_to_resolve const&)
+ else
{
cerr << c.file () << ":" << c.line () << ":" << c.column ()
- << ": error: unable to resolve type name '" << p
- << "' specified with '#pragma object pointer'" << endl;
+ << ": error: name '" << p << "' specified with "
+ << "'#pragma object pointer' does not name a type "
+ << "or a template" << endl;
throw generation_failed ();
}
@@ -464,16 +502,56 @@ namespace
if (p == "*")
ptr = name + "*";
else
+ {
ptr = p + "< " + name + " >";
+ tr1 = tr1
+ || p.compare (0, 8, "std::tr1") == 0
+ || p.compare (0, 10, "::std::tr1") == 0;
+ }
}
c.set ("object-pointer", ptr);
}
+ catch (invalid_name const& ex)
+ {
+ cerr << c.file () << ":" << c.line () << ":" << c.column ()
+ << ": error: type name '" << ex.name () << "' specified with "
+ << "'#pragma object pointer' is invalid" << endl;
+
+ throw generation_failed ();
+ }
+ catch (unable_to_resolve const& ex)
+ {
+ cerr << c.file () << ":" << c.line () << ":" << c.column ()
+ << ": error: unable to resolve type name '" << ex.name ()
+ << "' specified with '#pragma object pointer'" << endl;
+
+ throw generation_failed ();
+ }
}
private:
- struct invalid_name {};
- struct unable_to_resolve {};
+ struct invalid_name
+ {
+ invalid_name (string const& n): name_ (n) {}
+
+ string const&
+ name () const {return name_;}
+
+ private:
+ string name_;
+ };
+
+ struct unable_to_resolve
+ {
+ unable_to_resolve (string const& n): name_ (n) {}
+
+ string const&
+ name () const {return name_;}
+
+ private:
+ string name_;
+ };
tree
resolve_type (string const& qn, semantics::scope& ss)
@@ -491,7 +569,7 @@ namespace
if (b == 0)
scope = global_namespace;
else
- throw invalid_name ();
+ throw invalid_name (qn);
}
else
{
@@ -513,7 +591,7 @@ namespace
}
if (scope == error_mark_node)
- throw unable_to_resolve ();
+ throw unable_to_resolve (qn);
if (!last && TREE_CODE (scope) == TYPE_DECL)
scope = TREE_TYPE (scope);
@@ -523,7 +601,7 @@ namespace
break;
if (qn[++e] != ':')
- throw invalid_name ();
+ throw invalid_name (qn);
++e; // Second ':'.