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
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_paramet er;
template < typename T >
struct pointer_paramet er<T,true{
typedef T const * type;
};
template < typename T >
struct pointer_paramet er<T,false{
typedef T * type;
};
template < typename T, bool is_const >
struct reference_param eter;
template < typename T >
struct reference_param eter<T,true{
typedef T const & type;
};
template < typename T >
struct reference_param eter<T,false{
typedef T & type;
};
template < typename Target, typename C, bool is_const >
struct indexing_iterat or_base;
template < typename Target, typename C >
struct indexing_iterat or_base<Target, C,false:
public std::iterator< std::random_acc ess_iterator_ta g,
typename C::difference_t ype,
typename C::pointer,
typename C::reference >
{
C * the_container;
typename C::size_type the_index;
indexing_iterat or_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_iterat or_base<Target, C,true:
public std::iterator< std::random_acc ess_iterator_ta g,
typename C::difference_t ype,
typename C::const_pointe r,
typename C::const_refere nce >
{
C const * the_container;
typename C::size_type the_index;
indexing_iterat or_base ( C const * c,
typename C::size_type i )
: the_container ( c )
, the_index ( i )
{}
typename C::const_refere nce operator* ( void ) const {
return ( the_container->operator[]( the_index ) );
}
typename C::const_pointe r operator-( void ) const {
return ( & this->operator*() );
}
};
template < typename IndexedCont,
bool is_const = const_qualifier <IndexedCont>:: is_const >
struct indexing_iterat or
: public indexing_iterat or_base< indexing_iterat or<IndexedCont, is_const>,
IndexedCont, is_const >
{
typedef IndexedCont container_type;
typedef typename container_type: :size_type size_type;
private:
typedef indexing_iterat or_base< indexing_iterat or<IndexedCont, is_const>,
IndexedCont, is_const my_base;
using typename my_base::refere nce;
using typename my_base::pointe r;
public:
indexing_iterat or ( typename reference_param eter< container_type, is_const
>::type the_cont,
size_type the_index )
: my_base ( &the_cont, the_index )
{}
indexing_iterat or & operator++ ( void ) {
++ my_base::the_in dex;
return ( *this );
}
indexing_iterat or & operator-- ( void ) {
-- my_base::the_in dex;
return ( *this );
}
indexing_iterat or operator++ ( int ) {
indexing_iterat or result ( *this );
++ my_base::the_in dex;
return ( result );
}
indexing_iterat or operator-- ( int ) {
indexing_iterat or result ( *this );
-- my_base::the_in dex;
return ( result );
}
indexing_iterat or operator+= ( typename my_base::differ ence_type dist ) {
my_base::the_in dex += dist;
return ( *this );
}
indexing_iterat or operator-= ( typename my_base::differ ence_type dist ) {
my_base::the_in dex -= dist;
return ( *this );
}
indexing_iterat or operator+ ( typename my_base::differ ence_type dist )
const {
return
( indexing_iterat or
( &my_base::the_c ontainer, my_base::the_in dex + dist ) );
}
indexing_iterat or operator- ( typename my_base::differ ence_type dist )
const {
return
( indexing_iterat or
( &my_base::the_c ontainer, my_base::the_in dex - dist ) );
}
};
template < typename C, bool b >
typename indexing_iterat or<C,b>::differ ence_type
operator- ( indexing_iterat or<C,bconst & lhs,
indexing_iterat or<C,bconst & rhs ) {
assert( lhs.the_contain er == rhs.the_contain er );
return ( lhs.the_index - rhs.the_index );
}
template < typename C, bool b >
bool operator== ( indexing_iterat or<C,bconst & lhs,
indexing_iterat or<C,bconst & rhs ) {
assert( lhs.the_contain er == rhs.the_contain er );
return ( lhs.the_index == rhs.the_index );
}
template < typename C, bool b >
bool operator!= ( indexing_iterat or<C,bconst & lhs,
indexing_iterat or<C,bconst & rhs ) {
assert( lhs.the_contain er == rhs.the_contain er );
return ( lhs.the_index != rhs.the_index );
}
template < typename C, bool b >
bool operator< ( indexing_iterat or<C,bconst & lhs,
indexing_iterat or<C,bconst & rhs ) {
assert( lhs.the_contain er == rhs.the_contain er );
return ( lhs.the_index < rhs.the_index );
}
template < typename C, bool b >
bool operator<= ( indexing_iterat or<C,bconst & lhs,
indexing_iterat or<C,bconst & rhs ) {
assert( lhs.the_contain er == rhs.the_contain er );
return ( lhs.the_index <= rhs.the_index );
}
template < typename C, bool b >
bool operator( indexing_iterat or<C,bconst & lhs,
indexing_iterat or<C,bconst & rhs ) {
assert( lhs.the_contain er == rhs.the_contain er );
return ( lhs.the_index rhs.the_index );
}
template < typename C, bool b >
bool operator>= ( indexing_iterat or<C,bconst & lhs,
indexing_iterat or<C,bconst & rhs ) {
assert( lhs.the_contain er == rhs.the_contain er );
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_iterat or<pointiterato r;
iterator begin ( void ) {
return ( iterator( *this, 0 ) );
}
iterator end ( void ) {
return ( iterator( *this, 3 ) );
}
typedef indexing_iterat or<point constconst_iter ator;
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::lexicograp hical_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