Array index operator in 3d vector class
flag
Messages 9 - 18 of 18 - Collapse all
/groups/adfetch?adid=0aZiMxEAAACzEODE_QZQ70xINQVzkRHqFSRgCP-avRN4YT0eROC0jw
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Follow-up To:
Add Cc | Add Follow-up to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers that you hear
 
1.  kwikius  
View profile   Translate to Translated (View Original)
 More options 18 May 2006, 02:39
Newsgroups: comp.lang.c++.moderated
From: "kwikius" <a...@servocomm.freeserve.co.uk>
Date: 17 May 2006 21:39:26 -0400
Local: Thurs 18 May 2006 02:39
Subject: Array index operator in 3d vector class
I would like to use an array index operator in a 3D vector class, as an
alternative to accessing its x, y, z members directly, as I dont like
the function syntax as used in std::complex(e.g complex.real() ,
vect.x() etc).

Disregrading the fact that the array index operator in the following
vect class might technically use undefined behaviour, nevertheless
there isnt a way it can fail (assuming a valid index) , or is there?

regards
Andy Little

#include <stdexcept>
#include <cassert>

     template <typename T>
     struct vect
     {
         T x,y,z;

         T & operator[](int n)
         {
             if((n < 0)|| (n > 2)){
                 throw std::logic_error("array subscript out of range");
             }
             if( sizeof(vect) == 3 * sizeof(T)){
                 T * p = & x;
                 return p[n];
             }
             else{
                 switch (n){
                     case 0:
                         return x;
                     case 1 :
                         return y;
                     default:
                         return z;
                 }
             }
         }
         T const & operator[](int n)const
         {
             if( (n < 0) || (n > 2)){
                 throw std::logic_error("array subscript out of range");
             }
             if( sizeof(vect) == 3 * sizeof(T)){
                 T const * p = & x;
                 return p[n];
             }
             else{
                 switch (n){
                     case 0:
                         return x;
                     case 1 :
                         return y;
                     default:
                         return z;
                 }
             }
         }
         vect(): x(0),y(0),z(0){}
         /*
             Other operations omitted for clarity

             ...

         */
     };

int main()
{
     vect<double> v;
     v[0] = 2;
     double n = v.x;
     assert(v[0] == n);

}

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

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
2.  Victor Bazarov  
View profile   Translate to Translated (View Original)
 More options 18 May 2006, 22:26
Newsgroups: comp.lang.c++.moderated
From: "Victor Bazarov" <v.Abaza...@comAcast.net>
Date: 18 May 2006 17:26:23 -0400
Local: Thurs 18 May 2006 22:26
Subject: Re: Array index operator in 3d vector class

This is suspect.  'sizeof(vect)' is not necessarily 3 * sizeof(T) even
though the only three members are the three T's in it.  Generally speaking,
there can be padding of indeterminate size.

>                 T * p = & x;
>                 return p[n];
>             }
>             else{

[..]

V
--
Please remove capital As from my address when replying by mail

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


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
3.  kwikius  
View profile   Translate to Translated (View Original)
 More options 20 May 2006, 22:18
Newsgroups: comp.lang.c++.moderated
From: "kwikius" <a...@servocomm.freeserve.co.uk>
Date: 20 May 2006 17:18:21 -0400
Local: Sat 20 May 2006 22:18
Subject: Re: Array index operator in 3d vector class

OK,  but if  'sizeof(vect)' is not 3 * sizeof(T), then the offending
code is unreachable, so it isnt a problem AFAICS.

regards
Andy Little

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


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
4.  Antti Virtanen  
View profile   Translate to Translated (View Original)
 More options 18 May 2006, 23:39
Newsgroups: comp.lang.c++.moderated
From: Antti Virtanen <virta...@tilhi.cs.tut.fi>
Date: 18 May 2006 18:39:28 -0400
Local: Thurs 18 May 2006 23:39
Subject: Re: Array index operator in 3d vector class
On 2006-05-18, kwikius <a...@servocomm.freeserve.co.uk> wrote:

> Disregrading the fact that the array index operator in the following
> vect class might technically use undefined behaviour, nevertheless
> there isnt a way it can fail (assuming a valid index) , or is there?

I'm not sure, but I suspect trouble looms ahead. See below.

I don't see why you have the sizeof-if at all since the switch-case does the
trick in a safe fashion and efficiently. The compiler ought to figure out
how to make the switch-case structure efficient here. Assuming you still
want that sizeof-if, I'm not convinced of it's safety.

AFAIK it is guaranteed that things are allocated in the order of declaration
inside struct so that in a type struct bof { int a; int b; }; a is always
allocated before b in memory. I'm not sure, however, if this is the case
for struct bof { int a,b; }; If not, then T* p = &x; will obviously be a
problem.

Also, is the compiler allowed to allocate extra space between the members
of a struct? IMHO it is legal and may happen. If so, you have problems once
again.

Then there's the additional issue that someone might pass your template
a suprising type but I think we may leave this possibility out of the
discussion.

--
// Antti Virtanen -//- http://www.students.tut.fi/~virtanea -//- 050-4004278

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


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
5.  Carl Barron  
View profile   Translate to Translated (View Original)
 More options 18 May 2006, 23:39
Newsgroups: comp.lang.c++.moderated
From: Carl Barron <cbarron...@adelphia.net>
Date: 18 May 2006 18:39:03 -0400
Local: Thurs 18 May 2006 23:39
Subject: Re: Array index operator in 3d vector class
In article <1147911942.723852.258...@y43g2000cwc.googlegroups.com>,

  [snip]
    why not  just
     T &operator [](int n)
     {
       switch(n)
       {
       case 0: return x;
       case 1: return y;
       case 2: return z;
       default:throw std::logic_error(...);
       }
    }
   similiar for const version.

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


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
6.  kanze  
View profile   Translate to Translated (View Original)
 More options 20 May 2006, 21:47
Newsgroups: comp.lang.c++.moderated
From: "kanze" <ka...@gabi-soft.fr>
Date: 20 May 2006 16:47:25 -0400
Local: Sat 20 May 2006 21:47
Subject: Re: Array index operator in 3d vector class

I think that's the real question.  I don't think his version
will fail in any reasonable implementation, but I don't see the
point of it.  Your solution is far easier to read and
understand, will result in a smaller program, and will probably
be just as fast.

--
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! ]


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
7.  kwikius  
View profile   Translate to Translated (View Original)
 More options 23 May 2006, 12:15
Newsgroups: comp.lang.c++.moderated
From: "kwikius" <a...@servocomm.freeserve.co.uk>
Date: 23 May 2006 07:15:25 -0400
Local: Tues 23 May 2006 12:15
Subject: Re: Array index operator in 3d vector class

kanze wrote:

[...]

> I think that's the real question.  I don't think his version
> will fail in any reasonable implementation, but I don't see the
> point of it.  Your solution is far easier to read and
> understand, will result in a smaller program, and will probably
> be just as fast.

Right. There are 2 questions. (1) Is the code correct? (2) Why do this?

In this type of expression, losing one execution cycle is worth
spending some time on. The class is a template and therefore T could be
anything form a bool to a long double and beyond in size. I am making 3
assumptions:

1) The code is (in practise) correct for various T's, compilers and
OSes.

2)  it is trivial for the compiler to deduce that the condition  of the
if statement is a compile time constant, so for an optimising compiler
the code is equivalent to:

#if ( VECT_SIZE == THREE_SIZEOF_T)
                 T * p = & x;
                   return p[n];
#else
                   switch (n){
                       case 0:
                          return x;
                       case 1 :
                           return y;
                       default:
                           return z;
                }
#endif

3) That the array access version of the expression is always at least
as fast as and maybe faster than the switch statement.

Assuming those 3 assumptions hold I may gain something , but I appear
to lose nothing though after looking at Carl Barrons version, I see the
scheme may be compromised by the array bounds checking! Carls code
looks cleaner, however if the first ( correctness) assumption is wrong
it isnt worth considering alternative expressions to the switch AFAICS.

Thanks for all the replies.

regards
Andy Little

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


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
8.  kanze  
View profile   Translate to Translated (View Original)
 More options 24 May 2006, 16:39
Newsgroups: comp.lang.c++.moderated
From: "kanze" <ka...@gabi-soft.fr>
Date: 24 May 2006 11:39:51 -0400
Local: Wed 24 May 2006 16:39
Subject: Re: Array index operator in 3d vector class

kwikius wrote:
> kanze wrote:
> [...]
> > I think that's the real question.  I don't think his version
> > will fail in any reasonable implementation, but I don't see
> > the point of it.  Your solution is far easier to read and
> > understand, will result in a smaller program, and will
> > probably be just as fast.
> Right. There are 2 questions. (1) Is the code correct? (2) Why
> do this?

The answer to 2 is simply no.  But I think you know that; what
you mean to ask is will it work anyway?

> In this type of expression, losing one execution cycle is
> worth spending some time on. The class is a template and
> therefore T could be anything form a bool to a long double and
> beyond in size. I am making 3 assumptions:
> 1) The code is (in practise) correct for various T's,
> compilers and OSes.

You mean that it will probably work on most implementations.

That's probable.  Again, however, the question is why?  If using
an array is the appropriate solution, then just use an array.
If not, then use the switch.

> 3) That the array access version of the expression is always
> at least as fast as and maybe faster than the switch
> statement.

I'd run some benchmarks before I assumed such.  About the only
required extra cost you might have in the switch is bounds
checking (which is required by the standard in a switch).  The
array access is probably faster on most modern general purpose
machines, but I'd be sceptical in other cases.

Note too that as you originally wrote it, a clever compiler
could easily detect that p always pointed to a single element,
which means undefined behavior if n is not 0, which means that
the optimizer can suppose that n always is 0 (in the array
branch, at least), and replace the "return p[n]" with simply
"return x" (and of course, elimate all of the other code in the
function).

> Assuming those 3 assumptions hold I may gain something , but I
> appear to lose nothing though after looking at Carl Barrons
> version, I see the scheme may be compromised by the array
> bounds checking! Carls code looks cleaner, however if the
> first ( correctness) assumption is wrong it isnt worth
> considering alternative expressions to the switch AFAICS.

Well, if performance really is that critical, it's probably
worth implementing both versions and benchmarking them on
various target machines.  However, I would use two versions of
the data declaration as well -- array access with the data
declared as an array, and struct element access with the data
declared as a struct with three elements.  Mixing them will
certainly confuse the reader, and in some cases, may confuse the
compiler as well.

--
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! ]


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
9.  kwikius  
View profile   Translate to Translated (View Original)
 More options 26 May 2006, 04:26
Newsgroups: comp.lang.c++.moderated
From: "kwikius" <a...@servocomm.freeserve.co.uk>
Date: 25 May 2006 23:26:10 -0400
Local: Fri 26 May 2006 04:26
Subject: Re: Array index operator in 3d vector class

kanze wrote:
> Well, if performance really is that critical, it's probably
> worth implementing both versions and benchmarking them on
> various target machines.

These vects are intended to represent points in a scene which typically
comprises structures and arrays of large numbers of points. Performance
is important as the vect class is little more than a convenient point
container. Its main role is to give up it members.

> However, I would use two versions of
> the data declaration as well -- array access with the data
> declared as an array, and struct element access with the data
> declared as a struct with three elements.  Mixing them will
> certainly confuse the reader, and in some cases, may confuse the
> compiler as well.

Having used a 3D vect both as an array and with x,y,z members I
disagree. ( I dont think having 2 different classes for the same entity
is a good solution at all ! ).  I prefer to use the x,y,z notation when
its convenient and the array notation when that is more convenient.(
The array notation also relieves writing boiler plate code in functions
and numerous functions as shown in the example at the end --->

IIRC the same issue (allowing use of array access operations) came up
in relation to std::complex either on this list or comp.std.c++, though
I cant find the references at the moment.

As an example of the superiority of the array access approach in some
situations, imagine a function to detect whether two points are
touching  each other within a tolerance vector. Further assume that you
have two implement this for a 2Dand a 3D space. The array notation is
much more convenient. (I will leave the member version to do):

// type_trait to return the number of elements in a vect
template<typename T>
struct extent;

// Does vect a, touch vect b within the given tolerance?
// Vect may be a 2d or 3d vector
template <typename Vect>
bool touches( Vect const & a, Vect const & b, Vect const & tolerance)
{
     using boost::extent;
     for (int i = 0; i < extent<Vect>::value; ++i){
       using std::abs;
       if ( abs( a[i] - b[i]) > abs(tolerance[i]) ){
             return false;
       }
     }
     return true;

}

regards
Andy Little

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


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
10.  Oleg  
View profile   Translate to Translated (View Original)
 More options 20 May 2006, 04:31
Newsgroups: comp.lang.c++.moderated
From: "Oleg" <behol...@gorodok.net>
Date: 19 May 2006 23:31:12 -0400
Local: Sat 20 May 2006 04:31
Subject: Re: Array index operator in 3d vector class
Some time ago I've seen an interesting technique to implement indexing
for vector-like classes with fixed elements count. It simplifies code
(both implementation and usage), but can slow down things if your
compiler is not intelligent enough.

#include <stdexcept>

template <typename T>
struct vect
{
     struct { // to init by zeroes automatically (saves you from writing
of initialization list for default constructor)
         union {
             T data_[3];
             struct {
                 T x,y,z; // saves you from vec.x() syntax
             };
         };
     };

     T& operator[](int n)
     {
         if((n < 0)|| (n > 2)){
             throw std::logic_error("array subscript out of range");
         }
         return data_[n];
     }
     // NOTE: return by value for simple built-in types is better
     T operator[](int n)const
     {
         if( (n < 0) || (n > 2)){
             throw std::logic_error("array subscript out of range");
         }
         return data_[n];
     }
     vect() {}
     /*
         Other operations omitted for clarity

         ...

     */

};

#include <cassert>
#include <iostream>

int main()
{
      vect<double> v;
      assert(v.x == 0);
      assert(v.y == 0);
      assert(v.z == 0);
      v[0] = 2;
      v.y = 3;
      double n = v.x;
      assert(v[0] == n);

          std::cout << "Test passed\n";
      std::cin.get();

}

Best,
Oleg Abrosimov.

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


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google