Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > C++ Moderated > Re: C++ languag...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 15 of 16 Topic 9571 of 9823
Post > Topic >>

Re: C++ language: Cloneable cl*****

by =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@[EMAIL PROTECTED] May 10, 2008 at 02:13 PM

On 10 Mai, 05:26, Krzysztof Czainski <1czaj...@[EMAIL PROTECTED]
> wrote:
> On May 9, 5:15 pm, Daniel Krügler <daniel.krueg...@[EMAIL PROTECTED]
>
> wrote:
> > An interesting enhancement proposal for Cloneable could be to
> > add one further template parameter as smart-pointer policy
> > Yes, this is fine. And by means of the virtual inheritance you
> > simulate what other languages usually call "interface" (but
> > you know that). And if you use Cloneable<D, boost::shared_ptr<D> >
> > this will match the style of those languages even more ;-)
>
> Yes, exactly ;-)
>
> Here's the enhancement You proposed with another little enhancement of
> my own:
>
> [code]
> template < typename Derived, typename DefaultPtrPolicy =
> std::auto_ptr<Derived> >
> class Cloneable : public virtual CloneableBase
> {
> public:
>
>      BOOST_STATIC_ASSERT(( boost::is_base_of< Derived, typename
> DefaultPtrPolicy::element_type >::value ));
>
>      typedef DefaultPtrPolicy SmartPtr;
>
>      SmartPtr clone() const { return clone<SmartPtr>(); }
>
>      template < typename OtherPtrPolicy >
>      OtherPtrPolicy clone() const
>      {
>          BOOST_STATIC_ASSERT(( boost::is_base_of< Derived, typename
> OtherPtrPolicy::element_type >::value ));
>          // note: must be dynamic_cast due to virtual inheritance of
> CloneableBase
>          Derived* p = dynamic_cast<Derived*>( doClone() );
>          BOOST_ASSERT( p != NULL );
>          return OtherPtrPolicy( p );
>      }
>
> // note: the below would break compatibility with NaturallyCloneable
> //protected:
> //    Cloneable* doClone() const = 0;};
>
> [/code]
>
> Still, one thing bothers me.. The static assertion "is_base_of" should
> stay, but it would be nice to also be able to use a normal Derived*
> instead of some smart ptr type. Can that be achieved simply?
>
> class X : public Cloneable<X,X*>, NaturallyCloneable<X> {};

Hmmh, didn't you mean

class X : public Cloneable<X,X*>, public NaturallyCloneable<X> {};

instead?

This is not so hard to solve given Boost's type-traits.
In the following code I also replaced the inner
BOOST_STATIC_ASSERT of the clone template by a SFINAE
technique and I allowed for cv-qualified return types:

#include <memory>
#include <boost/static_assert.hpp>
#include <boost/assert.hpp>
#include <boost/cast.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/if.hpp>

template<typename T>
struct RemoveElementType {
	typedef typename T::element_type type;
};

template<typename Target, typename PtrPolicy>
struct MatchingPtrs : boost::integral_constant<bool,
	boost::is_base_of<Target, typename boost::remove_cv<
	   typename boost::mpl::if_<
	   boost::is_pointer<PtrPolicy>,
	   boost::remove_pointer<PtrPolicy>,
	   RemoveElementType<PtrPolicy>
	   >::type::type>::type>::value> {
};

template < typename Derived, typename DefaultPtrPolicy =
std::auto_ptr<Derived> >
class Cloneable : public virtual CloneableBase
{
public:
      BOOST_STATIC_ASSERT(( MatchingPtrs<Derived,
DefaultPtrPolicy>::value ));

      typedef DefaultPtrPolicy SmartPtr;

      SmartPtr clone() const { return clone<SmartPtr>(); }

      template < typename OtherPtrPolicy >
	 typename boost::enable_if<MatchingPtrs<Derived, OtherPtrPolicy>,
		 OtherPtrPolicy>::type clone() const
      {
          // note: must be dynamic_cast due to virtual inheritance of
CloneableBase
          Derived* p = dynamic_cast<Derived*>( doClone() );
          BOOST_ASSERT( p != NULL );
          return OtherPtrPolicy( p );
      }
};

class A : public Cloneable<A> {}; // abstract base for B and C
class B : public A, public NaturallyCloneable<B> {};
class C : public A { virtual A* doClone() const { return new C; } };
class X : public Cloneable<X,X*>, public NaturallyCloneable<X> {};

int main()
{
         B b;
         C c;
	X x;
         b.clone();
         c.clone();
         b.clone< boost::shared_ptr<A> >(); // see code below
         c.clone< boost::shared_ptr<A> >();
         c.clone< boost::shared_ptr<const volatile A> >();
         b.clone< A* >();
         c.clone< const A* >();
	x.clone();
	x.clone< boost::shared_ptr<X> >();
	x.clone< X* >();
}

HTH & Greetings from Bremen,

Daniel Krügler


-- 
      [ See http://www.gotw.ca/resources/clcm.htm
for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
 




 16 Posts in Topic:
C++ language: Cloneable classes
=?ISO-8859-2?Q?Krzysiek_C  2008-05-05 07:10:17 
Re: C++ language: Cloneable classes
Marsh Ray <marsh527@[E  2008-05-05 12:34:54 
Re: C++ language: Cloneable classes
Mathias Gaunard <loufo  2008-05-06 08:21:03 
Re: C++ language: Cloneable classes
=?ISO-8859-2?Q?Krzysiek_C  2008-05-06 08:43:26 
Re: C++ language: Cloneable classes
Krzysztof Czainski <1c  2008-05-06 12:46:54 
Re: C++ language: Cloneable classes
Mathias Gaunard <loufo  2008-05-06 18:43:26 
Re: C++ language: Cloneable classes
=?ISO-8859-1?Q?Daniel_Kr=  2008-05-06 18:43:26 
Re: C++ language: Cloneable classes
Krzysztof Czainski <1c  2008-05-07 11:08:38 
Re: C++ language: Cloneable classes
Krzysztof Czainski <1c  2008-05-07 11:43:27 
Re: C++ language: Cloneable classes
dizzy <dizzy@[EMAIL PR  2008-05-07 11:43:28 
Re: C++ language: Cloneable classes
=?ISO-8859-1?Q?Daniel_Kr=  2008-05-07 18:29:53 
Re: C++ language: Cloneable classes
Krzysztof Czainski <1c  2008-05-08 21:31:47 
Re: C++ language: Cloneable classes
=?ISO-8859-1?Q?Daniel_Kr=  2008-05-09 09:15:41 
Re: C++ language: Cloneable classes
Krzysztof Czainski <1c  2008-05-09 21:26:23 
Re: C++ language: Cloneable classes
=?ISO-8859-1?Q?Daniel_Kr=  2008-05-10 14:13:29 
Re: C++ language: Cloneable classes
Krzysztof Czainski <1c  2008-05-11 16:43:29 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Thu Jul 24 1:39:39 CDT 2008.