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 16 of 16 Topic 9571 of 9775
Post > Topic >>

Re: C++ language: Cloneable classes

by Krzysztof Czainski <1czajnik@[EMAIL PROTECTED] > May 11, 2008 at 04:43 PM

On 10 Maj, 22:13, Daniel Krügler <daniel.krueg...@[EMAIL PROTECTED]
>
wrote:

> > 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*>, public NaturallyCloneable<X> {};

> 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:
>
> 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 ));
> [...]

I figure there are 3 requirements for PtrPolicy:
1. Construct from Derived*
2. Dereferences (operator*) to a type which is base of Derived
3. operator-> returns a type which is base of Derived

PtrPolicy does not need to contain a typename element_type; only needs
to provide the above 3 requirements

For that I propose a concept Pointer; It's the first time I'm having
to do with writing concept requirements, so I don't even know if
that's the right way to do it, but seems to work for the example at
the bottom ;-)

[code]
#include <boost/concept_check.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_base_of.hpp>

namespace {

/** Type deduction will fail unless the arguments have the same type.
*/
template < typename Type >
inline void same_type( const volatile Type&, const volatile Type& ) {}

/** Type deduction will fail unless the pointers have the same type.
*/
template < typename Type >
inline void same_type_ptr( const volatile Type*, const volatile
Type* ) {}

/** Type deduction will fail unless Base is base of Derived. */
template < typename Base, typename Derived >
inline void base_of_type( const volatile Base&, const volatile
Derived& )
{
	BOOST_STATIC_ASSERT(( boost::is_base_of<Base,Derived>::value ));
}

/** Type deduction will fail unless Base is base of Derived. */
template < typename Base, typename Derived >
inline void base_of_type_ptr( const volatile Base*, const volatile
Derived* )
{
	BOOST_STATIC_ASSERT(( boost::is_base_of<Base,Derived>::value ));
}

} // namespace

/////////////////////////////////////////////////////////////////////////////

/** Pointer concept. */
template < typename Type, typename Ptr >
struct Pointer
{
	void constraints()
	{
		Ptr p( pType_ );
		base_of_type( *ptr_, type_ );
		base_of_type_ptr( ptr_.operator->(), pType_ );
	}

private:
	Type& type_;
	Type* pType_;
	Ptr& ptr_;
};

/** Pointer concept. Specialization for classic pointers. */
template < typename Type, typename Base >
struct Pointer<Type,Base*>
{
	void constraints()
	{
		Base* p( pType_ );
		p = p; // avoid unused warning
	}

private:
	Type* pType_;
};
[/code]

And now in Cloneable<>:

[code]
template < typename Derived, typename DefaultPtrPolicy =
std::auto_ptr<Derived> >
class Cloneable : public virtual CloneableBase
{
     BOOST_CLASS_REQUIRE2( Derived, DefaultPtrPolicy, , Pointer );
[...]
     /** @[EMAIL PROTECTED]
 aCI */
     template < typename OtherPtrPolicy >
     OtherPtrPolicy clone() const
     {
         boost::function_requires< Pointer<Derived,OtherPtrPolicy> >();
[...]
[/code]

And the example used previously with some extras:

[code]
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> {};

class Y : public A, public Cloneable< Y, boost::shared_ptr<A> >,
public NaturallyCloneable<Y> {};

// for testing Pointer concept:
template < typename Type, typename Ptr >
void f()
{
	boost::function_requires< Pointer<Type,Ptr> >();
}

// for testing Pointer concept:
template < typename Type, typename Ptr >
class Z
{
	BOOST_CLASS_REQUIRE2( Type, Ptr, , Pointer );
};

int main()
{
	f<A,A::SmartPtr>();
	f<X,X::SmartPtr>();
//	f<A,B>(); // error
	f<B,A*>();
//	f<A,B*>(); // error
	f< Y, boost::shared_ptr<A> >();

	Z<A,A::SmartPtr>();
	Z<X,X::SmartPtr>();
//	Z<A,B>(); // error
	Z<B,A*>();
//	Z<A,B*>(); // error
	Z< Y, boost::shared_ptr<A> >();

	//A a; // error: abstract type
	B b;
	C c;
	b.clone();
	c.clone();
	b.clone< boost::shared_ptr<A> >();
	c.clone< boost::shared_ptr<A> >();
	c.clone< boost::shared_ptr<const volatile A> >();
	b.clone< A* >();
	c.clone< const A* >();
	X x;
	x.clone();
}
[/code]

I've learned so much from this discussion, and I feel there's much
ahead of me too ;-D
Cheers


-- 
      [ 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 Tue Jul 8 23:37:58 CDT 2008.