Connecting Tech Pros Worldwide Help | Site Map

union float[3] and x,y,z

 
LinkBack Thread Tools Search this Thread
  #1  
Old September 25th, 2007, 12:35 PM
Gernot Frisch
Guest
 
Posts: n/a
Default union float[3] and x,y,z

Uhm...
Is there any way of making
float pos[3];
a union of
float x,y,z;

somehow, so I can use:


mything[0] = mything.y;
instead of mything.x = mything.y

Thanks in advice,

--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}




  #2  
Old September 25th, 2007, 12:55 PM
Alexander Dong Back Kim
Guest
 
Posts: n/a
Default Re: union float[3] and x,y,z

On Sep 25, 10:26 pm, "Gernot Frisch" <M...@Privacy.netwrote:
Quote:
Uhm...
Is there any way of making
float pos[3];
a union of
float x,y,z;
>
somehow, so I can use:
>
mything[0] = mything.y;
instead of mything.x = mything.y
>
Thanks in advice,
>
--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}
Hi Gernot,

Just a thought. How about making a structure and overriding operators?


Cheers,

  #3  
Old September 25th, 2007, 12:55 PM
Victor Bazarov
Guest
 
Posts: n/a
Default Re: union float[3] and x,y,z

Gernot Frisch wrote:
Quote:
Uhm...
Is there any way of making
float pos[3];
a union of
float x,y,z;
>
somehow, so I can use:
>
>
mything[0] = mything.y;
instead of mything.x = mything.y
>
Thanks in advice,
Hasn't this been discussed here a couple of times over the past
two-three months? No, there is no sense in making a union. The
only way you can manage that is if you stuff 'x', 'y', and 'x' in
some kind of struct inside that union. In structs members can
have padding, and in arrays they don't. So, it is conceivable
that your union trick is not going to work. A solution might be

struct Blah {
float pos[3];
float &x, &y, &z;
Blah() : x(pos[0]), y(pos[1]), z(pos[2]) {}
};

which makes it non-POD (members that are references). Or agree
to define 'x' as a function:

struct Blah {
float pos[3];
float& x() { return pos[0]; }
float x() const { return pos[0]; }
};

In any case, search the archives for "union padding array" and
some other keywords you can come up with.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


  #4  
Old September 25th, 2007, 01:25 PM
=?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=
Guest
 
Posts: n/a
Default Re: union float[3] and x,y,z

On 2007-09-25 14:26, Gernot Frisch wrote:
Quote:
Uhm...
Is there any way of making
float pos[3];
a union of
float x,y,z;
>
somehow, so I can use:
>
>
mything[0] = mything.y;
instead of mything.x = mything.y
No, however you can do something like this:

struct thing
{
float arr[3];
float& x;
float& y;
float& z;

thing() : x(arr[0]), y(arr[1]), z(arr[2]) {}
};

Which allows you to access x through either t.x or through t.arr[0]
where t is an object of type thing:

int main()
{
thing t;
t.x = 1;
t.y = 2;
t.arr[2] = 3;

int i = 0;
}

If you want to be able to use t[0] instead of t.arr[0] you have to
overload the [] operator as Alexander Dong Back Kim suggested.

--
Erik Wikström
  #5  
Old September 25th, 2007, 01:35 PM
Victor Bazarov
Guest
 
Posts: n/a
Default Re: union float[3] and x,y,z

Erik Wikström wrote:
Quote:
On 2007-09-25 14:26, Gernot Frisch wrote:
Quote:
>Uhm...
>Is there any way of making
>float pos[3];
>a union of
>float x,y,z;
>>
>somehow, so I can use:
>>
>>
>mything[0] = mything.y;
>instead of mything.x = mything.y
>
No, however you can do something like this:
>
struct thing
{
float arr[3];
float& x;
float& y;
float& z;
>
thing() : x(arr[0]), y(arr[1]), z(arr[2]) {}
};
>
Which allows you to access x through either t.x or through t.arr[0]
where t is an object of type thing:
>
int main()
{
thing t;
t.x = 1;
t.y = 2;
t.arr[2] = 3;
>
int i = 0;
}
>
If you want to be able to use t[0] instead of t.arr[0] you have to
overload the [] operator as Alexander Dong Back Kim suggested.
Actually, could still do that if you do this trick:

struct thing {
float x, y, z;
struct thing_indexing {
thing& t;
thing_indexing(thing& t) : t(t) {}
float& operator[](int i) {
return i < 2 ? i < 1 ? t.x : t.y : t.z;
}
} arr;
thing() : arr(*this) {}
thing& operator=(thing const& t) {
x = t.x;
y = t.y;
z = t.z;
}
};

int main() {
thing t;
t.x = 3.1415926;
t.arr[1] = t.x;
}

RATS! I got pulled in and am writing code when I didn't want to....

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


  #6  
Old September 25th, 2007, 03:55 PM
=?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=
Guest
 
Posts: n/a
Default Re: union float[3] and x,y,z

On 2007-09-25 15:26, Victor Bazarov wrote:
Quote:
Erik Wikstr�m wrote:
Quote:
>On 2007-09-25 14:26, Gernot Frisch wrote:
Quote:
>>Uhm...
>>Is there any way of making
>>float pos[3];
>>a union of
>>float x,y,z;
>>>
>>somehow, so I can use:
>>>
>>>
>>mything[0] = mything.y;
>>instead of mything.x = mything.y
>>
>No, however you can do something like this:
>>
>struct thing
>{
> float arr[3];
> float& x;
> float& y;
> float& z;
>>
> thing() : x(arr[0]), y(arr[1]), z(arr[2]) {}
>};
>>
>Which allows you to access x through either t.x or through t.arr[0]
>where t is an object of type thing:
>>
>int main()
>{
>thing t;
>t.x = 1;
>t.y = 2;
>t.arr[2] = 3;
>>
>int i = 0;
>}
>>
>If you want to be able to use t[0] instead of t.arr[0] you have to
>overload the [] operator as Alexander Dong Back Kim suggested.
>
Actually, could still do that if you do this trick:
>
struct thing {
float x, y, z;
struct thing_indexing {
thing& t;
thing_indexing(thing& t) : t(t) {}
float& operator[](int i) {
return i < 2 ? i < 1 ? t.x : t.y : t.z;
}
} arr;
thing() : arr(*this) {}
thing& operator=(thing const& t) {
x = t.x;
y = t.y;
z = t.z;
}
};
>
int main() {
thing t;
t.x = 3.1415926;
t.arr[1] = t.x;
}
>
RATS! I got pulled in and am writing code when I didn't want to....
Sorry, but I just cannot understand the reason for this construct. To me
it looks like it provides exactly the same functionality as my code,
except that I used an array and you used a struct with an overloaded []
operator. Please, enlighten me.

--
Erik Wikström
  #7  
Old September 25th, 2007, 05:05 PM
Victor Bazarov
Guest
 
Posts: n/a
Default Re: union float[3] and x,y,z

Erik Wikström wrote:
Quote:
On 2007-09-25 15:26, Victor Bazarov wrote:
Quote:
>Erik Wikstr?m wrote:
Quote:
>>On 2007-09-25 14:26, Gernot Frisch wrote:
>>>Uhm...
>>>Is there any way of making
>>>float pos[3];
>>>a union of
>>>float x,y,z;
>>>>
>>>somehow, so I can use:
>>>>
>>>>
>>>mything[0] = mything.y;
>>>instead of mything.x = mything.y
>>>
>>No, however you can do something like this:
>>>
>>struct thing
>>{
>> float arr[3];
>> float& x;
>> float& y;
>> float& z;
>>>
>> thing() : x(arr[0]), y(arr[1]), z(arr[2]) {}
>>};
>>>
>>Which allows you to access x through either t.x or through t.arr[0]
>>where t is an object of type thing:
>>>
>>int main()
>>{
>>thing t;
>>t.x = 1;
>>t.y = 2;
>>t.arr[2] = 3;
>>>
>>int i = 0;
>>}
>>>
>>If you want to be able to use t[0] instead of t.arr[0] you have to
>>overload the [] operator as Alexander Dong Back Kim suggested.
>>
>Actually, could still do that if you do this trick:
>>
> struct thing {
> float x, y, z;
> struct thing_indexing {
> thing& t;
> thing_indexing(thing& t) : t(t) {}
> float& operator[](int i) {
> return i < 2 ? i < 1 ? t.x : t.y : t.z;
> }
> } arr;
> thing() : arr(*this) {}
> thing& operator=(thing const& t) {
> x = t.x;
> y = t.y;
> z = t.z;
> }
> };
>>
> int main() {
> thing t;
> t.x = 3.1415926;
> t.arr[1] = t.x;
> }
>>
>RATS! I got pulled in and am writing code when I didn't want to....
>
Sorry, but I just cannot understand the reason for this construct. To
me it looks like it provides exactly the same functionality as my
code, except that I used an array and you used a struct with an
overloaded [] operator. Please, enlighten me.
It was a facetious suggestion, so that the OP could use 'arr' to get
to the members, not just the indexing operator (working from your
original suggestion to use 'thing.arr[0]' syntax).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


  #8  
Old September 26th, 2007, 04:05 AM
Jim Langston
Guest
 
Posts: n/a
Default Re: union float[3] and x,y,z

"Victor Bazarov" <v.Abazarov@comAcast.netwrote in message
news:fdbetr$rct$1@news.datemas.de...
Quote:
Erik Wikström wrote:
Quote:
>On 2007-09-25 15:26, Victor Bazarov wrote:
Quote:
>>Erik Wikstr?m wrote:
>>>On 2007-09-25 14:26, Gernot Frisch wrote:
>>>>Uhm...
>>>>Is there any way of making
>>>>float pos[3];
>>>>a union of
>>>>float x,y,z;
>>>>>
>>>>somehow, so I can use:
>>>>>
>>>>>
>>>>mything[0] = mything.y;
>>>>instead of mything.x = mything.y
>>>>
>>>No, however you can do something like this:
>>>>
>>>struct thing
>>>{
>>> float arr[3];
>>> float& x;
>>> float& y;
>>> float& z;
>>>>
>>> thing() : x(arr[0]), y(arr[1]), z(arr[2]) {}
>>>};
>>>>
>>>Which allows you to access x through either t.x or through t.arr[0]
>>>where t is an object of type thing:
>>>>
>>>int main()
>>>{
>>>thing t;
>>>t.x = 1;
>>>t.y = 2;
>>>t.arr[2] = 3;
>>>>
>>>int i = 0;
>>>}
>>>>
>>>If you want to be able to use t[0] instead of t.arr[0] you have to
>>>overload the [] operator as Alexander Dong Back Kim suggested.
>>>
>>Actually, could still do that if you do this trick:
>>>
>> struct thing {
>> float x, y, z;
>> struct thing_indexing {
>> thing& t;
>> thing_indexing(thing& t) : t(t) {}
>> float& operator[](int i) {
>> return i < 2 ? i < 1 ? t.x : t.y : t.z;
>> }
>> } arr;
>> thing() : arr(*this) {}
>> thing& operator=(thing const& t) {
>> x = t.x;
>> y = t.y;
>> z = t.z;
>> }
>> };
>>>
>> int main() {
>> thing t;
>> t.x = 3.1415926;
>> t.arr[1] = t.x;
>> }
>>>
>>RATS! I got pulled in and am writing code when I didn't want to....
>>
>Sorry, but I just cannot understand the reason for this construct. To
>me it looks like it provides exactly the same functionality as my
>code, except that I used an array and you used a struct with an
>overloaded [] operator. Please, enlighten me.
>
It was a facetious suggestion, so that the OP could use 'arr' to get
to the members, not just the indexing operator (working from your
original suggestion to use 'thing.arr[0]' syntax).
Isn't this functionality what the OP asked for, what Alexander was
suggesting?

struct thing
{
float x, y, z;
float& operator[]( size_t Index )
{
switch ( Index )
{
case 0:
return x;
case 1:
return y;
case 2:
return z;
default:
throw "Bad Index";
}
}
};

I'm confused where this "arr" come in, I don't see it in the OP.


  #9  
Old September 26th, 2007, 06:35 AM
Kai-Uwe Bux
Guest
 
Posts: n/a
Default Re: union float[3] and x,y,z

Gernot Frisch wrote:
Quote:
Uhm...
Is there any way of making
float pos[3];
a union of
float x,y,z;
>
somehow, so I can use:
>
>
mything[0] = mything.y;
instead of mything.x = mything.y
Why stop there? why not make point a container:

#include <cstddef>
#include <cassert>
#include <iterator>
#include <functional>
#include <algorithm>

template < typename T >
struct const_qualifier {

typedef T type;

typedef T mutable_type;
typedef T const const_type;

static bool const is_const = false;

};

template < typename T >
struct const_qualifier< T const {

typedef T const type;

typedef T mutable_type;
typedef T const const_type;

static bool const is_const = true;

};

template < typename T, bool is_const >
struct pointer_parameter;

template < typename T >
struct pointer_parameter<T,true{

typedef T const * type;

};

template < typename T >
struct pointer_parameter<T,false{

typedef T * type;

};

template < typename T, bool is_const >
struct reference_parameter;

template < typename T >
struct reference_parameter<T,true{

typedef T const & type;

};

template < typename T >
struct reference_parameter<T,false{

typedef T & type;

};

template < typename Target, typename C, bool is_const >
struct indexing_iterator_base;

template < typename Target, typename C >
struct indexing_iterator_base<Target,C,false:
public std::iterator< std::random_access_iterator_tag,
typename C::difference_type,
typename C::pointer,
typename C::reference >
{
C * the_container;
typename C::size_type the_index;

indexing_iterator_base ( C * c,
typename C::size_type i )
: the_container ( c )
, the_index ( i )
{}

typename C::reference operator* ( void ) {
return ( the_container->operator[]( the_index ) );
}

typename C::pointer operator-( void ) {
return ( & this->operator*() );
}

};

template < typename Target, typename C >
struct indexing_iterator_base<Target,C,true:
public std::iterator< std::random_access_iterator_tag,
typename C::difference_type,
typename C::const_pointer,
typename C::const_reference >
{

C const * the_container;
typename C::size_type the_index;

indexing_iterator_base ( C const * c,
typename C::size_type i )
: the_container ( c )
, the_index ( i )
{}

typename C::const_reference operator* ( void ) const {
return ( the_container->operator[]( the_index ) );
}

typename C::const_pointer operator-( void ) const {
return ( & this->operator*() );
}

};

template < typename IndexedCont,
bool is_const = const_qualifier<IndexedCont>::is_const >
struct indexing_iterator
: public indexing_iterator_base< indexing_iterator<IndexedCont,is_const>,
IndexedCont, is_const >
{

typedef IndexedCont container_type;
typedef typename container_type::size_type size_type;

private:

typedef indexing_iterator_base< indexing_iterator<IndexedCont,is_const>,
IndexedCont, is_const my_base;

using typename my_base::reference;
using typename my_base::pointer;

public:

indexing_iterator ( typename reference_parameter< container_type, is_const
Quote:
>::type the_cont,
size_type the_index )
: my_base ( &the_cont, the_index )
{}

indexing_iterator & operator++ ( void ) {
++ my_base::the_index;
return ( *this );
}

indexing_iterator & operator-- ( void ) {
-- my_base::the_index;
return ( *this );
}

indexing_iterator operator++ ( int ) {
indexing_iterator result ( *this );
++ my_base::the_index;
return ( result );
}

indexing_iterator operator-- ( int ) {
indexing_iterator result ( *this );
-- my_base::the_index;
return ( result );
}

indexing_iterator operator+= ( typename my_base::difference_type dist ) {
my_base::the_index += dist;
return ( *this );
}

indexing_iterator operator-= ( typename my_base::difference_type dist ) {
my_base::the_index -= dist;
return ( *this );
}

indexing_iterator operator+ ( typename my_base::difference_type dist )
const {
return
( indexing_iterator
( &my_base::the_container, my_base::the_index + dist ) );
}

indexing_iterator operator- ( typename my_base::difference_type dist )
const {
return
( indexing_iterator
( &my_base::the_container, my_base::the_index - dist ) );
}

};

template < typename C, bool b >
typename indexing_iterator<C,b>::difference_type
operator- ( indexing_iterator<C,bconst & lhs,
indexing_iterator<C,bconst & rhs ) {
assert( lhs.the_container == rhs.the_container );
return ( lhs.the_index - rhs.the_index );
}

template < typename C, bool b >
bool operator== ( indexing_iterator<C,bconst & lhs,
indexing_iterator<C,bconst & rhs ) {
assert( lhs.the_container == rhs.the_container );
return ( lhs.the_index == rhs.the_index );
}

template < typename C, bool b >
bool operator!= ( indexing_iterator<C,bconst & lhs,
indexing_iterator<C,bconst & rhs ) {
assert( lhs.the_container == rhs.the_container );
return ( lhs.the_index != rhs.the_index );
}

template < typename C, bool b >
bool operator< ( indexing_iterator<C,bconst & lhs,
indexing_iterator<C,bconst & rhs ) {
assert( lhs.the_container == rhs.the_container );
return ( lhs.the_index < rhs.the_index );
}

template < typename C, bool b >
bool operator<= ( indexing_iterator<C,bconst & lhs,
indexing_iterator<C,bconst & rhs ) {
assert( lhs.the_container == rhs.the_container );
return ( lhs.the_index <= rhs.the_index );
}

template < typename C, bool b >
bool operator( indexing_iterator<C,bconst & lhs,
indexing_iterator<C,bconst & rhs ) {
assert( lhs.the_container == rhs.the_container );
return ( lhs.the_index rhs.the_index );
}

template < typename C, bool b >
bool operator>= ( indexing_iterator<C,bconst & lhs,
indexing_iterator<C,bconst & rhs ) {
assert( lhs.the_container == rhs.the_container );
return ( lhs.the_index >= rhs.the_index );
}


struct point {

typedef float value_type;

typedef value_type & reference;
typedef value_type const & const_reference;
typedef value_type * pointer;
typedef value_type const * const_pointer;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;

value_type x, y, z;

point ( float x_, float y_, float z_ )
: x ( x_ )
, y ( y_ )
, z ( z_ )
{}

value_type const & operator[] ( std::size_t i ) const {
assert( i < 3 );
return ( (*this).*proxy() [i] );
}

value_type & operator[] ( std::size_t i ) {
assert( i < 3 );
return ( (*this).*proxy() [i] );
}

typedef indexing_iterator<pointiterator;

iterator begin ( void ) {
return ( iterator( *this, 0 ) );
}

iterator end ( void ) {
return ( iterator( *this, 3 ) );
}

typedef indexing_iterator<point constconst_iterator;

const_iterator begin ( void ) const {
return ( const_iterator( *this, 0 ) );
}

const_iterator end ( void ) const {
return ( const_iterator( *this, 3 ) );
}


private:

static
value_type point::* const * const proxy ( void ) {
static value_type point::* const dummy [3] =
{ &point::x, &point::y, &point::z };
return ( dummy );
}

};

namespace std {

template <>
struct less< point {

bool operator() ( point const & lhs, point const & rhs ) {
return ( std::lexicographical_compare( lhs.begin(), lhs.end(),
rhs.begin(), rhs.end() ) );
}

};

} // namespace std

#include <iostream>
#include <iomanip>


int main ( void ) {
point p ( 1, 1, 1 );
point q ( 1, 1, 1.1 );
std::cout << std::boolalpha << std::less<point>()( p, q ) << '\n';
p.x = q[2];
std::cout << p.x << '\n';
}


Just kidding :-)

However: hidden in the above code is yet another answer to your question.


Best

Kai-Uwe Bux
 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 220,840 network members.