[beast: 1/26] BSE: allow BseObject->as<shared_ptr<Type>>() conversions



commit 385eda016b37859ff3427008e2c102c2cf2a6f51
Author: Tim Janik <timj gnu org>
Date:   Mon Jun 29 04:33:01 2015 +0200

    BSE: allow BseObject->as<shared_ptr<Type>>() conversions

 bse/bsecontainer.cc     |    2 +-
 bse/bsecontextmerger.cc |    2 +-
 bse/bseitem.cc          |    2 +-
 bse/bseobject.hh        |   16 +++++++++++++++-
 bse/bseserver.cc        |    4 ++--
 bse/bsesource.cc        |    2 +-
 bse/bsesuper.cc         |    2 +-
 7 files changed, 22 insertions(+), 8 deletions(-)
---
diff --git a/bse/bsecontainer.cc b/bse/bsecontainer.cc
index 3be9ba5..e37263a 100644
--- a/bse/bsecontainer.cc
+++ b/bse/bsecontainer.cc
@@ -1363,7 +1363,7 @@ ContainerImpl::lookup_item (const String &uname)
 {
   BseContainer *self = as<BseContainer*>();
   BseItem *child = bse_container_lookup_item (self, uname.c_str());
-  return child ? shared_ptr_cast<ItemIface> (child->as<ItemIface*>()) : ItemIfaceP();
+  return child->as<ItemIfaceP>();
 }
 
 } // Bse
diff --git a/bse/bsecontextmerger.cc b/bse/bsecontextmerger.cc
index 450f1a7..b7d6d71 100644
--- a/bse/bsecontextmerger.cc
+++ b/bse/bsecontextmerger.cc
@@ -220,6 +220,6 @@ ContextMergerImpl::~ContextMergerImpl ()
 {}
 
 // BseContextMerger *self = as<BseContextMerger*>();
-// shared_ptr_cast<ContextMergerIface> (contextmerger->as<ContextMergerIface*>())
+// contextmerger->as<ContextMergerIfaceP>()
 
 } // Bse
diff --git a/bse/bseitem.cc b/bse/bseitem.cc
index c529c38..5f401ab 100644
--- a/bse/bseitem.cc
+++ b/bse/bseitem.cc
@@ -1341,7 +1341,7 @@ ItemImpl::common_ancestor (ItemIface &other)
   BseItem *self = as<BseItem*>();
   BseItem *bo = other.as<BseItem*>();
   BseItem *common = bse_item_common_ancestor (self, bo);
-  return common ? shared_ptr_cast<ItemIface> (common->as<ItemIface*>()) : ItemIfaceP();
+  return common->as<ItemIfaceP>();
 }
 
 } // Bse
diff --git a/bse/bseobject.hh b/bse/bseobject.hh
index 6ceff71..1806cf9 100644
--- a/bse/bseobject.hh
+++ b/bse/bseobject.hh
@@ -64,7 +64,12 @@ struct BseObject : GObject {
   guint16               lock_count;
   guint                         unique_id;
   operator               Bse::ObjectImpl* ()          { return cxxobject_; }
-  template<class ObjectImplPtr>
+  // DERIVES_shared_ptr (uses void_t to prevent errors for T without shared_ptr's typedefs)
+  template<class T, typename = void> struct DERIVES_shared_ptr : std::false_type {};
+  template<class T> struct DERIVES_shared_ptr<T, Rapicorn::void_t< typename T::element_type > > :
+  std::is_base_of< std::shared_ptr<typename T::element_type>, T > {};
+  // as<T*>()
+  template<class ObjectImplPtr, typename ::std::enable_if<std::is_pointer<ObjectImplPtr>::value, bool>::type 
= true>
   ObjectImplPtr          as ()
   {
     static_assert (std::is_pointer<ObjectImplPtr>::value, "");
@@ -72,6 +77,15 @@ struct BseObject : GObject {
     static_assert (std::is_base_of<Rapicorn::Aida::ImplicitBase, ObjectImplT>::value, "");
     return dynamic_cast<ObjectImplPtr> (cxxobject_);
   }
+  // as<shared_ptr<T>>()
+  template<class ObjectImplP, typename ::std::enable_if<DERIVES_shared_ptr<ObjectImplP>::value, bool>::type 
= true>
+  ObjectImplP            as ()
+  {
+    typedef typename ObjectImplP::element_type ObjectImplT;
+    static_assert (std::is_base_of<Rapicorn::Aida::ImplicitBase, ObjectImplT>::value, "");
+    ObjectImplT *impl = this && cxxobject_ ? as<ObjectImplT*>() : NULL;
+    return impl ? Rapicorn::shared_ptr_cast<ObjectImplT> (impl) : NULL;
+  }
 };
 
 G_BEGIN_DECLS // BseObject templates need C++ linkage
diff --git a/bse/bseserver.cc b/bse/bseserver.cc
index a909e3a..c1015b3 100644
--- a/bse/bseserver.cc
+++ b/bse/bseserver.cc
@@ -1127,7 +1127,7 @@ ServerImpl::from_proxy (int64_t proxyid)
   BseObject *bo = bse_object_from_id (proxyid);
   if (!bo)
     return ObjectIfaceP();
-  return shared_ptr_cast<ObjectIface> (bo->as<ObjectIface*>());
+  return bo->as<ObjectIfaceP>();
 }
 
 ServerImpl&
@@ -1462,7 +1462,7 @@ ServerImpl::create_project (const String &project_name)
   g_object_connect (project,
                    "signal::release", release_project, server,
                    NULL);
-  return shared_ptr_cast<ProjectIface> (project->as<ProjectIface*>());
+  return project->as<ProjectIfaceP>();
 }
 
 void
diff --git a/bse/bsesource.cc b/bse/bsesource.cc
index b6dc206..1861308 100644
--- a/bse/bsesource.cc
+++ b/bse/bsesource.cc
@@ -2083,7 +2083,7 @@ SourceImpl::ichannel_get_osource (int input_channel, int input_joint)
     osource = input->idata.osource;
   else
     osource = NULL;
-  return osource ? shared_ptr_cast<SourceIface> (osource->as<SourceIface*>()) : SourceIfaceP();
+  return osource->as<SourceIfaceP>();
 }
 
 } // Bse
diff --git a/bse/bsesuper.cc b/bse/bsesuper.cc
index 0c56d8f..63786f9 100644
--- a/bse/bsesuper.cc
+++ b/bse/bsesuper.cc
@@ -234,6 +234,6 @@ SuperImpl::~SuperImpl ()
 {}
 
 // BseSuper *self = as<BseSuper*>();
-// SuperIfaceP sp = shared_ptr_cast<SuperIface> (super->as<SuperIface*>());
+// SuperIfaceP sp = super->as<SuperIfaceP>();
 
 } // Bse


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]