On Jun 18, 6:28*pm, "Alf P. Steinbach" <al...@start.no> wrote:
> * abir, on 18.06.2010 14:00:
>
> > I have an custom allocator implementation whose base type depends on
> > completeness of the type parameter T, though the nested types doesn't
> > depend on so.
>
> > e.g.
>
> > template<typename T>
> > struct is_Small
> > {
> > * * const static bool value = (sizeof(T)< *sizeof(void*) );
> > };
>
> Probably you mean "<=" here, not "<".
>
doesn't matter. My criterion for is_small may be different from yours.
>
>
> > template<typename T> *struct impl1{};
> > template<typename T> *struct impl2{};
>
> > template<typename T>
> > struct my_alloc : private select<is_small<T> *, impl1<T> *, impl2<T>
> > > ::type
> > {
> > * *typedef T* pointer;
> > * *...
> > };
>
> > struct foo; //incomplete type.
> > typedef my_alloc<foo>:
ointer foo_ptr;
>
> > The same problem are supposed to happen for stack_alloc<T,N> *also, as
> > usually they has std::aligned_storage as memory.
>
> What is the problem?
>
typedef my_alloc<foo>:

ointer foo_ptr;
The above statement is not allowed, as foo is incomplete type.
> You can not determine the size of an incomplete type and it makes no sense to
> try to allocate storage to hold an instance of such a type.
>
Where am I allocating storage for an incomplete type?
I am only interested to have to have the above typedef which doesn't
work at present
as the base class selection for my_alloc depends on completeness of
foo.
> Also, what is 'stack_alloc<T, N>'?
>
I am sure you know, but still for completeness,
#include <tr1/type_traits>
template<typename T,unsigned N>
struct stack_alloc
{
typedef T* pointer;
std::tr1::aligned_storage<(sizeof(T)*N),
std::tr1::alignment_of<T>::value> buffer_;
};
struct foo;
typedef stack_alloc<foo,10>:

ointer foo_ptr;
The line above won't work as foo is incomplete type, though I am only
interested to typedef nested type.
> > So far with std::allocator these wasn't a problem though it's allocate
> > function is usually
> > return operator new (sizeof(T) *n);
>
> > * I can pull the traits in a separate class as
> > template<typename T>
> > struct alloc_traits
> > {
> > * *typedef T* pointer ; ...
> > };
>
> > and use it as
> > typedef alloc_traits<foo>:
ointer foo_ptr;
>
> > But then I need to change the code everywhere.
>
> Why would you do that?
>
See the reason above. I am interested to typedef pointer type of an
allocator of incomplete type.
When I create such an allocator object, I will surely have complete
type of foo available.
> > Is it possible to design my_alloc such as the nested types which are
> > independent can still work where rest of functionality depends on
> > completeness of T ?
>
> Please provide a complete example exhibiting the problem.
>
> Copy and paste the code, do not retype it manually.
I didn't had my working PC connected to network, now I have.
The code below is NOT compilable.
template<typename T>
struct is_small
{
const static bool value = sizeof(T) <= sizeof(void*);
//i am putting <= , as sure you know what i am trying to do.
//though i use part of the pointer for other purpose, so it
//is actually < instead of <=
};
template<typename T> struct impl1{};
template<typename T> struct impl2{};
template<bool B,typename T1,typename T2>
struct select
{
typedef T1 type;
};
template<typename T1,typename T2>
struct select<false,T1,T2>
{
typedef T2 type;
};
template<typename T>
struct my_alloc : private select< is_small<T>::value,impl1<T>,
impl2<T> >
{
typedef T* pointer;
};
struct foo;
typedef my_alloc<foo>:

ointer foo_ptr;
struct bar;
typedef my_alloc<bar>:

ointer bar_ptr;
//and later
struct foo{};
struct bar{};
I want to make it compilable without having full definition of foo
available for typedef to foo_ptr.
And I prefer to change my_alloc in such a way keeping its
functionality same so that I won't have to change every typedef to
foo_ptr , bar_ptr.
> The FAQ item about how to post a question about Code That Does Not Work provides
> some good advice for formulating your question in a way so that it might be
> answered.
>
> > Or even is it possible to define some lazy_typedef which don't try to
> > instantiate the class.
>
> You can always specialize your 'is_Small' for any type, even an incomplete one.
>
That is not what I want. I want to alias nested types of my_alloc
which doesn't depend on completeness of T.
The solution presently i have is to pull those inner types in a
separate class as alloc_traits
as shown
template<typename T>
struct alloc_traits
{
typedef T* pointer;
};
struct foo;
typedef alloc_traits<foo>:

ointer foo_ptr;
struct bar;
typedef alloc_traits<bar>:

ointer bar_ptr;
I do not like this solution as I have to change all of the typedefs .
Looking for a solution where I have to change only my_alloc
or a generic solution which will delay the completeness checking.
> But it makes no sense to try to allocate storage for an instance of an
> incomplete type.
>
I know. But no where i am creating storage for incomplete type. Only
interested to have a typedef to pointer nested type of an allocator
for incomplete type. And I believe pointer of an incomplete type
should be allowed all allocators including std::allocator., whatever
may be implementation is.
> > I need the pointers to be defined for incomplete type for any
> > allocator, as otherwise many cyclic dependency will happen.
>
> Cheers & hth.,
>
> - Alf
>
> --
Hope it clears the confusion.
> blog at <url:http://alfps.wordpress.com>
Thanks