From dfc260adf46e79b039685d554797b403d76c6bfd Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 22 Jun 2015 18:08:32 +0200 Subject: Implement member type mapping, more m.type() cleanups --- odb/common.hxx | 8 ++++---- odb/context.cxx | 43 +++++++++++++++++++++++++++++++++++++++++-- odb/context.hxx | 22 ++++++++++++---------- odb/processor.cxx | 3 +-- odb/relational/common.txx | 2 +- odb/relational/source.cxx | 12 ++++++------ odb/relational/source.hxx | 8 ++++---- 7 files changed, 69 insertions(+), 29 deletions(-) diff --git a/odb/common.hxx b/odb/common.hxx index ba9dd2d..104351a 100644 --- a/odb/common.hxx +++ b/odb/common.hxx @@ -33,7 +33,7 @@ struct object_members_base: traversal::class_, virtual context // bases and members. The first argument is the data member and can // be NULL if we are traversing the root type or a base. The second // argument is the actual composite type, which is not necessarily - // the same as m.type (). + // the same as the member's type. // virtual void traverse_composite (semantics::data_member*, semantics::class_&); @@ -49,8 +49,8 @@ struct object_members_base: traversal::class_, virtual context semantics::class_& comp, semantics::type* wrapper); - // The second argument is the actual container type in case m.type () - // is a wrapper. + // The second argument is the actual container type in case the + // member type is a wrapper. // virtual void traverse_container (semantics::data_member&, semantics::type&); @@ -196,7 +196,7 @@ struct object_columns_base: traversal::class_, virtual context // bases and members. The first argument is the data member and can // be NULL if we are traversing the root type or a base. The second // argument is the actual composite type, which is not necessarily - // the same as m.type (). + // the same as the member type. // virtual void traverse_composite (semantics::data_member*, semantics::class_&); diff --git a/odb/context.cxx b/odb/context.cxx index 737138a..aa7c744 100644 --- a/odb/context.cxx +++ b/odb/context.cxx @@ -644,7 +644,6 @@ context (ostream& os_, include_regex (data_->include_regex_), accessor_regex (data_->accessor_regex_), modifier_regex (data_->modifier_regex_), - custom_type_map (u.get ("custom-cxx-type-map")), embedded_schema ( ops.generate_schema () && ops.schema_format ()[db].count (schema_format::embedded)), @@ -762,7 +761,6 @@ context () include_regex (current ().include_regex), accessor_regex (current ().accessor_regex), modifier_regex (current ().modifier_regex), - custom_type_map (current ().custom_type_map), embedded_schema (current ().embedded_schema), separate_schema (current ().separate_schema), multi_static (current ().multi_static), @@ -1198,6 +1196,47 @@ utype (semantics::data_member& m, semantics::names*& hint, string const& kp) } } + // Do we need to map this type? + // + // @@ Need to cache the result on the member. + // + for (semantics::scope* s (&m.scope ());; s = &s->scope_ ()) + { + using semantics::namespace_; + + if (namespace_* ns = dynamic_cast (s)) + { + if (ns->extension ()) + s = &ns->original (); + } + + if (s->count ("custom-cxx-type-map")) + { + typedef custom_cxx_type_map map; + + map& m (s->get ("custom-cxx-type-map")); + map::const_iterator i (m.find (t)); + + if (i != m.end ()) + { + cerr << "mapping " << t->fq_name (hint) << " to "; + + hint = i->second->as_hint; + t = i->second->as; + + cerr << t->fq_name (hint) << endl; + + // Currently we only support one level of mapping, but I am + // sure someone will want multiple levels. + // + break; + } + } + + if (s->global_scope ()) + break; + } + return *t; } diff --git a/odb/context.hxx b/odb/context.hxx index e743a4a..e74aeb1 100644 --- a/odb/context.hxx +++ b/odb/context.hxx @@ -646,10 +646,14 @@ public: static bool const_type (semantics::type&); - // Form a reference type for a member type. If make_const is true, then - // add top-level const qualifier, unless it is already there. If it is - // false, then strip it if it is already there. If var is not empty, - // then embed the variable name into the type (e.g., char (*v)[3]). + static bool + const_member (semantics::data_member& m) {return const_type (m.type ());} + + // Form a reference type for a not mapped, actual member type. If + // make_const is true, then add top-level const qualifier, unless + // it is already there. If it is false, then strip it if it is + // already there. If var is not empty, then embed the variable + // name into the type (e.g., char (*v)[3]). // static string member_ref_type (semantics::data_member& m, @@ -665,10 +669,10 @@ public: bool make_const, string const& var = ""); - // Form a value type for a member type. If make_const is true, then add - // top-level const qualifier, unless it is already there. If it is false, - // then strip it if it is already there. If var is not empty, then embed - // the variable name into the type (e.g., char v[3]). + // Form a value type for a not mapped, actual member type. If make_const + // is true, then add top-level const qualifier, unless it is already + // there. If it is false, then strip it if it is already there. If var is + // not empty, then embed the variable name into the type (e.g., char v[3]). // static string member_val_type (semantics::data_member& m, @@ -1723,8 +1727,6 @@ public: regex_mapping const& accessor_regex; regex_mapping const& modifier_regex; - custom_cxx_type_map const& custom_type_map; - bool embedded_schema; bool separate_schema; diff --git a/odb/processor.cxx b/odb/processor.cxx index ee143e2..c281706 100644 --- a/odb/processor.cxx +++ b/odb/processor.cxx @@ -143,8 +143,7 @@ namespace // auto_ptr - can modify by setting a new pointer // const auto_ptr - can modify by changing the pointed-to value // - if (const_type (m.type ()) && - !(id (m) || version (m) || m.count ("inverse"))) + if (const_member (m) && !(id (m) || version (m) || m.count ("inverse"))) { if (qwt == 0 || const_type (*qwt)) m.set ("readonly", true); diff --git a/odb/relational/common.txx b/odb/relational/common.txx index d428068..7a3adad 100644 --- a/odb/relational/common.txx +++ b/odb/relational/common.txx @@ -25,7 +25,7 @@ namespace relational var = name + (name[name.size () - 1] == '_' ? "" : "_"); } - bool cq (type_override_ != 0 ? false : const_type (m.type ())); + bool cq (type_override_ != 0 ? false : const_member (m)); semantics::type& t (type_override_ != 0 ? *type_override_ : utype (m)); semantics::type* cont; diff --git a/odb/relational/source.cxx b/odb/relational/source.cxx index 4bb8e9d..97e7ea0 100644 --- a/odb/relational/source.cxx +++ b/odb/relational/source.cxx @@ -1299,7 +1299,7 @@ traverse_object (type& c) // then cast away constness. Otherwise, we assume that the user- // provided expression handles this. // - bool cast (ma.direct () && const_type (id->type ())); + bool cast (ma.direct () && const_member (*id)); if (cast) os << "const_cast< id_type& > (" << endl; @@ -1334,7 +1334,7 @@ traverse_object (type& c) // then cast away constness. Otherwise, we assume that the user- // provided expression handles this. // - bool cast (opt_ma_set->direct () && const_type (opt->type ())); + bool cast (opt_ma_set->direct () && const_member (*opt)); if (cast) os << "const_cast< version_type& > (" << endl; @@ -1558,7 +1558,7 @@ traverse_object (type& c) // then cast away constness. Otherwise, we assume that the user- // provided expression handles this. // - bool cast (ma.direct () && const_type (id->type ())); + bool cast (ma.direct () && const_member (*id)); if (cast) os << "const_cast< id_type& > (" << endl; @@ -1593,7 +1593,7 @@ traverse_object (type& c) // then cast away constness. Otherwise, we assume that the user- // provided expression handles this. // - bool cast (opt_ma_set->direct () && const_type (opt->type ())); + bool cast (opt_ma_set->direct () && const_member (*opt)); if (cast) os << "const_cast< version_type& > (" << endl; @@ -2140,7 +2140,7 @@ traverse_object (type& c) // then cast away constness. Otherwise, we assume that the user- // provided expression handles this. // - bool cast (opt_ma_set->direct () && const_type (opt->type ())); + bool cast (opt_ma_set->direct () && const_member (*opt)); if (cast) os << "const_cast< version_type& > (" << endl; @@ -2459,7 +2459,7 @@ traverse_object (type& c) // then cast away constness. Otherwise, we assume that the user- // provided expression handles this. // - bool cast (opt_ma_set->direct () && const_type (opt->type ())); + bool cast (opt_ma_set->direct () && const_member (*opt)); if (cast) os << "const_cast< version_type& > (" << endl; diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx index 53034ac..56949d6 100644 --- a/odb/relational/source.hxx +++ b/odb/relational/source.hxx @@ -5066,7 +5066,7 @@ namespace relational // that the user-provided expression handles this. // bool cast ( - call_ == load_call && ma.direct () && const_type (m->type ())); + call_ == load_call && ma.direct () && const_member (*m)); if (cast) obj_prefix_ = "const_cast< " + member_ref_type (*m, false) + " > (\n"; @@ -5090,7 +5090,7 @@ namespace relational semantics::names* hint; semantics::type& t (utype (*m, hint)); - // Because we cannot have nested containers, m.type () should + // Because we cannot have nested containers, member type should // be the same as w. // assert (&t == w); @@ -5211,7 +5211,7 @@ namespace relational // that the user-provided expression handles this. // bool cast ( - call_ == load_call && ma.direct () && const_type (m.type ())); + call_ == load_call && ma.direct () && const_member (m)); if (cast) os << "const_cast< " << member_ref_type (m, false) << " > (" << endl; @@ -6353,7 +6353,7 @@ namespace relational // access, then cast away constness. Otherwise, we assume // that the user-provided expression handles this. // - bool cast (ma_set.direct () && const_type (opt->type ())); + bool cast (ma_set.direct () && const_member (*opt)); if (cast) os << "const_cast< version_type& > (" << endl; -- cgit v1.1