Boost logo

Boost :

Subject: Re: [boost] [concept_check] Some issues
From: Robert Kawulak (robert.kawulak_at_[hidden])
Date: 2011-12-03 10:39:11


> From: Stewart, Robert
> > > > - The implementation of assignable_archetype defines
> > > > private default and copy constructors, so for example
> > > > assignable_archetype<copy_constructible_archetype<>> will
> > > > not actually be copy constructible. The same for
> > > > convertible_to_archetype and convertible_from_archetype,
> > > > but additionally with copy assignment. Is this by purpose?
> > >
> > > I should think that's by design. The archetypes are to
> > > validate a particular concept checking class, so a copyable
> > > or default constructible archetype for Assignable would be
> > > wrong.
> >
> > I wouldn't say it's wrong. If you can combine several concepts,
> > you should be able to combine the corresponding archetypes too.
> > If your template requires more than one concept (e.g., a type
> > that is BOTH copyable AND assignable), then without the ability
> > of chaining you would have to write your own archetypes in all
> > but the most trivial cases.
>
> I would. The purpose of an Assignable archetype is to test that a type
> that is assignable, but possibly neither default nor copy
> constructible, satisfies the concept. That is, the Assignable concept
> checker should not impose *any* other criteria on its parameterizing
> type.

I guess you could've misunderstood what I ask for - it's not making the
extra special functions public but rather removing them completely. This
allows for composition while still it's not making the archetypes looser
than required. The actual code I use is:

  template <typename T = int>
  class null_archetype
  {
      null_archetype();
      null_archetype(const null_archetype &);
      null_archetype & operator = (const null_archetype &);
      ~null_archetype();
  };

  template < typename Base = null_archetype<> >
  struct copy_constructible_archetype : public Base
  {
      copy_constructible_archetype(const copy_constructible_archetype &);
      ~copy_constructible_archetype();
  };

  template < typename Base = null_archetype<> >
  struct assignable_archetype : public Base
  {
      assignable_archetype & operator = (const assignable_archetype &);
  };

How is assignable_archetype<> default or copy constructible now? It's not
unless you combine it - for example only
assignable_archetype<copy_constructible_archetype<>> is both assignable and
copy constructible.

In comparison, the current implementation of the classes is:

  template <class T = int>
  class null_archetype {
  private:
    null_archetype() { }
    null_archetype(const null_archetype&) { }
    null_archetype& operator=(const null_archetype&) { return *this; }
  public:
    null_archetype(detail::dummy_constructor) { }
  };

  template <class Base = null_archetype<> >
  class copy_constructible_archetype : public Base {
  public:
    copy_constructible_archetype()
      : Base(static_object<detail::dummy_constructor>::get()) { }
    copy_constructible_archetype(const copy_constructible_archetype&)
      : Base(static_object<detail::dummy_constructor>::get()) { }
    copy_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
  };

  template <class Base = null_archetype<> >
  class assignable_archetype : public Base {
    assignable_archetype() { }
    assignable_archetype(const assignable_archetype&) { }
  public:
    assignable_archetype& operator=(const assignable_archetype&) { return
*this; }
    assignable_archetype(detail::dummy_constructor x) : Base(x) { }
  };

Now:
- assignable_archetype<copy_constructible_archetype<>> is not copy
constructible,
- assignable_archetype<default_constructible_archetype<>> is not default
constructible,
- copy_constructible_archetype<> is also default constructible,
- assignable_archetype<> is also destructible (which it doesn't necessarily
have to be).

Either I'm overlooking something or the current implementation is simply
wrong and needs to be fixed.

> > > Even if so, not all combinations are possible.
> >
> > Could you give an example of an impossible combination?
>
> The OP's! Seriously, my point is that making a particular archetype
> restrict its interface might generally prevent certain combinations.

But why you'd want to prevent certain combinations at all? Is there anything
wrong with combining archetypes? If not, than an archetype doesn't have to
(and shouldn't) restrict its interface (by "restricting" I don't mean "not
providing", but "prevent from providing by combined archetypes"). Assuming
you use null_archetype as the root base class, you don't need to restrict
anything because it is sufficient not to declare functions that are not
needed. They will not be provided unless you chain the archetype with
another archetype that provides them. OTOH, restricting them will
practically break chaining (as it does now).

> In order to make the Assignable archetype neither default nor copy
> constructible, to ensure that the concept checker doesn't require those
> capabilities, it cannot be combined with CopyConstructible's or
> DefaultConstructible's archetypes, at least not as the derivate.

Sorry, but could you give a code example? I still don't see your point.
assignable_archetype<> defined as above is not copy nor default
constructible.
assignable_archetype<default_constructible_archetype<copy_constructible_arch
etype<>>> is.

Do you mean that chaining archetypes like this should be forbidden? If so,
why? After all, if you can combine concepts, you must be able to combine
archetypes as well or otherwise you're not able to test the concepts at all.
For example, if you have a function template:

template<typename T>
void f(const T &)
{
  BOOST_CONCEPT_ASSERT((Assignable<T>));
  BOOST_CONCEPT_ASSERT((CopyConstructible<T>));
  ...
}

Then how do you test this function without chaining? You have to write your
own simple archetype that combines assignable_archetype<> and
copy_constructible_archetype<>. I don't see any point in doing this
repetitive and error-prone work when you could simply use
assignable_archetype<copy_constructible_archetype<>>.

Best regards,
Robert


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk