C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

SOLUTION: compile time array size using type only
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
dmitry.sychov@mail.ru
Guest





PostPosted: Thu Sep 07, 2006 11:29 pm    Post subject: SOLUTION: compile time array size using type only Reply with quote



Hi

here is the way for finding array size using type only

////////
template<class T> class cx_array_length {
template <class T, unsigned N> static inline const char
(&_bounds_fn(const T (&)[N]))[N];
static const T * _arr;
public:
enum { value = sizeof(_bounds_fn(*_arr)) }; };


int length = cx_array_length<char[3]>::value;

//////////


the question is: is the compiler is smart enough not to put "_arr" into
the compiled object?

if you have better solutions/any ideas please share

regards, dmitry


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Thomas Maeder
Guest





PostPosted: Fri Sep 08, 2006 4:55 am    Post subject: Re: SOLUTION: compile time array size using type only Reply with quote



"dmitry.sychov (AT) mail (DOT) ru" <dmitry.sychov (AT) mail (DOT) ru> writes:

Quote:
here is the way for finding array size using type only

////////
template<class T> class cx_array_length {
template <class T, unsigned N> static inline const char
(&_bounds_fn(const T (&)[N]))[N];
static const T * _arr;
public:
enum { value = sizeof(_bounds_fn(*_arr)) }; };


int length = cx_array_length<char[3]>::value;

//////////


the question is: is the compiler is smart enough not to put "_arr"
into the compiled object?

if you have better solutions/any ideas please share

What about:

template <typename T>
class cx_array_length
{
enum
{
value = 1
};
};

template <typename T, unsigned N>
struct cx_array_length<T[N]>
{
enum
{
value = N
};
};


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Alf P. Steinbach
Guest





PostPosted: Fri Sep 08, 2006 4:57 am    Post subject: Re: SOLUTION: compile time array size using type only Reply with quote



* dmitry.sychov (AT) mail (DOT) ru:
Quote:

here is the way for finding array size using type only

////////
template<class T> class cx_array_length {
template <class T, unsigned N> static inline const char

It would be a good idea to use std::size_t instead of unsigned here.

Also, 'inline' is superfluous.


Quote:
(&_bounds_fn(const T (&)[N]))[N];
static const T * _arr;
public:
enum { value = sizeof(_bounds_fn(*_arr)) }; };


int length = cx_array_length<char[3]>::value;

//////////


the question is: is the compiler is smart enough not to put "_arr" into
the compiled object?

The number of tails a dog has depends on the dog, and is not mentioned
in the Holy Standard. ;-)


Quote:
if you have better solutions/any ideas please share

template< typename T > T const& aCompileTimeValueOf(); // No impl.

typedef SomeType X[1234];
std::size_t const length = N_ELEMENTS( aCompileTimeValueOf<X>() );

where N_ELEMENTS is any strictly compile time argument evaluation
number-of-elements-in-array macro.

Since you addressed the "using type only" aspect you're probably aware
of the techniques available when you have an actual array instance at
hand, i.e. how N_ELEMENTS could be implemented, but for those who aren't
familiar with this, see <url:
http://home.no.net/dubjai/win32cpptut/special/pointers/array_size.doc.pdf>
(which perhaps should be updated with Dmitry's technique/aspect).

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
lhyatt@princeton.edu
Guest





PostPosted: Fri Sep 08, 2006 5:03 am    Post subject: Re: SOLUTION: compile time array size using type only Reply with quote

dmitry.sychov (AT) mail (DOT) ru wrote:
Quote:
Hi

here is the way for finding array size using type only

////////
template<class T> class cx_array_length {
template <class T, unsigned N> static inline const char
(&_bounds_fn(const T (&)[N]))[N];
static const T * _arr;
public:
enum { value = sizeof(_bounds_fn(*_arr)) }; };


int length = cx_array_length<char[3]>::value;

//////////


the question is: is the compiler is smart enough not to put "_arr" into
the compiled object?

Since _arr is a static member, you are going to need to declare it in a
translation unit somewhere, and space will be allocated for it once,
which isn't such a big deal.

Quote:
if you have better solutions/any ideas please share

you can use the size of an array as a template parameter, so you could
do this much more directly with partial specialization, like this:

//define a general template for non-array types
template<typename InvalidType>
struct array_length {
enum {value=0};
//could also force a compile-time error here, with
BOOST_STATIC_ASSERT
};

//specialize it for array types
template<typename T, std::size_t N>
struct array_length<T[N]> {
enum {value=N};
};

Now you have eg array_length<char[3]>::value = 3 as a compile time
constant.

-lewis


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






PostPosted: Fri Sep 08, 2006 9:12 pm    Post subject: Re: SOLUTION: compile time array size using type only Reply with quote

dmitry.sychov (AT) mail (DOT) ru wrote:
Quote:
Hi

here is the way for finding array size using type only

////////
template<class T> class cx_array_length {
template <class T, unsigned N> static inline const char
(&_bounds_fn(const T (&)[N]))[N];
static const T * _arr;
public:
enum { value = sizeof(_bounds_fn(*_arr)) }; };


int length = cx_array_length<char[3]>::value;

//////////


the question is: is the compiler is smart enough not to put "_arr" into
the compiled object?


You don't need _arr - just cast 0 into a T * or T & - it is not
evaluated inside the sizeof. Some may argue that technically it
invokes undef behaviour, I'm not sure, but this is not a case where I'd
be concerned.


Quote:
if you have better solutions/any ideas please share


Thomas Maeder's looks better to me. Quite elegant. I only mention the
above stuff in case it helps elsewhere.

Quote:
regards, dmitry



Tony


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





PostPosted: Fri Sep 08, 2006 9:19 pm    Post subject: Re: SOLUTION: compile time array size using type only Reply with quote

Thomas Maeder wrote:
Quote:
"dmitry.sychov (AT) mail (DOT) ru" <dmitry.sychov (AT) mail (DOT) ru> writes:

here is the way for finding array size using type only

////////
template<class T> class cx_array_length {
template <class T, unsigned N> static inline const char
(&_bounds_fn(const T (&)[N]))[N];
static const T * _arr;
public:
enum { value = sizeof(_bounds_fn(*_arr)) }; };

int length = cx_array_length<char[3]>::value;

//////////

the question is: is the compiler is smart enough not to put
"_arr" into the compiled object?

If I understand the standard correctly, it isn't allowed to
instantiate the definition (and couldn't if it was, since you
haven't provided a definition) unless you use it.

Quote:
if you have better solutions/any ideas please share

What about:

template <typename T
class cx_array_length
{
enum
{
value = 1
};
};

template <typename T, unsigned N
struct cx_array_length<T[N]
{
enum
{
value = N
};
};

But what's the point. In both cases, in order to instantiate
the template, you have to specify the type, to specify the type,
you have to specify the size literally, and if you know the
size, it's much easier to write just:
int length = 3 ;
than
int length = cx_array_length< int[ 3 ] >::value ;
Or is there something here that I've missed?

We (you and I) recently did something more useful in
de.comp.lang.iso-c++, if I recall correctly:

template< typename N, size_t N >
char (&array_size( T (&array)[ N ] ))[ N ] ;

which allows writing things like:

double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = sizeof( array_size( someArray ) ) ;

Obviously, the problem is even easier if you don't require a
constant integral expression.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


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





PostPosted: Fri Sep 08, 2006 9:20 pm    Post subject: Re: SOLUTION: compile time array size using type only Reply with quote

lhyatt (AT) princeton (DOT) edu wrote:
Quote:
dmitry.sychov (AT) mail (DOT) ru wrote:

here is the way for finding array size using type only

////////
template<class T> class cx_array_length {
template <class T, unsigned N> static inline const char
(&_bounds_fn(const T (&)[N]))[N];
static const T * _arr;
public:
enum { value = sizeof(_bounds_fn(*_arr)) }; };

int length = cx_array_length<char[3]>::value;
//////////

the question is: is the compiler is smart enough not to put
"_arr" into the compiled object?

Since _arr is a static member, you are going to need to
declare it in a translation unit somewhere, and space will be
allocated for it once, which isn't such a big deal.

Only if it is actually instantiated (the static member, not the
class). And it should only be instatiated if it is actually
used, which it isn't.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


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






PostPosted: Tue Sep 12, 2006 6:47 am    Post subject: Re: SOLUTION: compile time array size using type only Reply with quote

kanze wrote:
Quote:

But what's the point. In both cases, in order to instantiate
the template, you have to specify the type, to specify the type,
you have to specify the size literally, and if you know the
size, it's much easier to write just:
int length = 3 ;
than
int length = cx_array_length< int[ 3 ] >::value ;
Or is there something here that I've missed?


I was wondering the same thing, but I suspect there may be times when
'int[3]' is only known as T - ie maybe this helps in other template
code?

Tony


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
John Moeller
Guest





PostPosted: Wed Sep 13, 2006 4:44 am    Post subject: Re: SOLUTION: compile time array size using type only Reply with quote

kanze wrote:
,,,
Quote:
template< typename N, size_t N
char (&array_size( T (&array)[ N ] ))[ N ] ;

which allows writing things like:

double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = sizeof( array_size( someArray ) ) ;
....


As an aside, I'm curious; could you not just have easily written:

template< typename T, size_t N >
size_t array_size( T (& array)[ N ] ) { return N; }

so that you could have written:

double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = array_size( someArray ) ;

thus directly obtaining the array size, rather than using sizeof? I
have to assume there's a reason that I'm missing. Either way, I think
that the technique is great; I'll have to remember it for future use.

John Moeller


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Hendrik Schober
Guest





PostPosted: Wed Sep 13, 2006 8:53 pm    Post subject: Re: SOLUTION: compile time array size using type only Reply with quote

John Moeller <fishcorn (AT) gmail (DOT) com> wrote:
Quote:
kanze wrote:
,,,
template< typename N, size_t N
char (&array_size( T (&array)[ N ] ))[ N ] ;

which allows writing things like:

double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = sizeof( array_size( someArray ) ) ;
...

As an aside, I'm curious; could you not just have easily written:

template< typename T, size_t N
size_t array_size( T (& array)[ N ] ) { return N; }

so that you could have written:

double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = array_size( someArray ) ;

thus directly obtaining the array size, rather than using sizeof? I
have to assume there's a reason that I'm missing. [...]

Yours is a run-time solution, James' yields a compile-time
constant.

Schobi

--
SpamTrap (AT) gmx (DOT) de is never read
I'm Schobi at suespammers dot org

"The sarcasm is mightier than the sword."
Eric Jarvis



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





PostPosted: Wed Sep 13, 2006 8:54 pm    Post subject: Re: SOLUTION: compile time array size using type only Reply with quote

John Moeller wrote:
Quote:
kanze wrote:

template< typename N, size_t N
char (&array_size( T (&array)[ N ] ))[ N ] ;

which allows writing things like:

double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = sizeof( array_size( someArray ) ) ;
...

As an aside, I'm curious; could you not just have easily written:

template< typename T, size_t N
size_t array_size( T (& array)[ N ] ) { return N; }

so that you could have written:

double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = array_size( someArray ) ;

thus directly obtaining the array size, rather than using sizeof?

In this case, yes, and in fact, that is the way it is done in my
own library. The solution above came about as a result of a
discussion in de.comp.lang.iso_c++, where it was also desired to
be able to do something like:

double secondArray[ sizeof( array_size( firstArray ) ) ] ;

That's what I meant when I said: "Obviously, the problem is even
easier if you don't require a constant integral expression."

(Unless I'm using static initialization, or the initialization
list is being used to determine the size, my arrays are always
std::vector. Which means that I don't need a constant integral
expression. So my code uses the simple forms:

template< typename T, size_t N >
size_t
size( T (&array)[ N ] )
{
return N ;
}

and the equivalent for begin() and end(). The names of the
functions being chosen, of course, to correspond to those of the
member functions in an STL container.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Gennaro Prota
Guest





PostPosted: Wed Sep 13, 2006 11:40 pm    Post subject: Re: SOLUTION: compile time array size using type only Reply with quote

On 13 Sep 2006 11:54:44 -0400, "kanze" <kanze@gabi-soft.fr> wrote:

Quote:
In this case, yes, and in fact, that is the way it is done in my
own library. The solution above came about as a result of a
discussion in de.comp.lang.iso_c++, where it was also desired to
be able to do something like:

double secondArray[ sizeof( array_size( firstArray ) ) ] ;

I don't doubt that you independently reinvented it, however I first
saw that tecnique in code by Dietmar Kuehl. IIRC it was code written
before year 2000.

I wrote a generalized version for multidimensional arrays which was
available in the boost vault. I plan to make an even more general
version, supporting tr1::array (and thus size==0), available under the
GPL. Of course the plain function is enough for most purposes. And
generalized constant expressions proposed by B. Stroustrup & G. Dos
Reis would give the best of both worlds.

--
Gennaro Prota

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





PostPosted: Thu Sep 14, 2006 5:10 pm    Post subject: Re: SOLUTION: compile time array size using type only Reply with quote

Gennaro Prota wrote:
Quote:
On 13 Sep 2006 11:54:44 -0400, "kanze" <kanze@gabi-soft.fr> wrote:

In this case, yes, and in fact, that is the way it is done in
my own library. The solution above came about as a result of
a discussion in de.comp.lang.iso_c++, where it was also
desired to be able to do something like:

double secondArray[ sizeof( array_size( firstArray ) ) ] ;

I don't doubt that you independently reinvented it, however I
first saw that tecnique in code by Dietmar Kuehl. IIRC it was
code written before year 2000.

It wouldn't surprise me. I don't claim to have "invented" it.
I do think that anyone familiar with template meta-programming
today, even in it's simplest forms, would come up with it, given
the normal begin(), end() and size() functions (which I didn't
invent either, but heard about somewhere, although I don't
remember where). It wouldn't surprise me either that Dietmar
invented it before 2000, when it wouldn't have been at all
evident; he's one of the most gifted programmers I know.

I mentionned the discussion in de.comp.lang.iso_c++ only because
I was responding to Thomas Maeder, who had mentionned it there
not more than a week ago.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


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





PostPosted: Sun Sep 17, 2006 3:58 pm    Post subject: Re: SOLUTION: compile time array size using type only Reply with quote

John Moeller wrote:
Quote:
As an aside, I'm curious; could you not just have easily written:

template< typename T, size_t N
size_t array_size( T (& array)[ N ] ) { return N; }

so that you could have written:

double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = array_size( someArray ) ;


Can someone explain how that works? I can't work out how the value
for template parameter N is determined when all you pass to the
array_size function is the array ptr.

Thanks
Adrian.


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





PostPosted: Mon Sep 18, 2006 12:06 am    Post subject: Re: SOLUTION: compile time array size using type only Reply with quote

Adrian wrote:

Quote:

John Moeller wrote:
As an aside, I'm curious; could you not just have easily written:

template< typename T, size_t N
size_t array_size( T (& array)[ N ] ) { return N; }

so that you could have written:

double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
int length = array_size( someArray ) ;


Can someone explain how that works? I can't work out how the value
for template parameter N is determined when all you pass to the
array_size function is the array ptr.


You're not. The function is being passed a reference to an array of
size N.

Of course, this assumes that the compiler has enough information, within
the scope where the function is called, to know it is working with an
array. The following would result in an error;


size_t intermediary(double *v)
{
return array_size(v);
}

int main()
{
double someArray[] = { 0.1, 0.2, 0.5, 1.0 } ;
size_t length = intermediary(someArray);

}

as the only information available to the compiler, at the point where
array_size() is called, is a pointer which includes no size information.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.