Gernot said:
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:
ointer,
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:
ointer 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:
ointer;
public:
indexing_iterator ( typename reference_parameter< container_type, is_const
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,b> const & lhs,
indexing_iterator<C,b> const & 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,b> const & lhs,
indexing_iterator<C,b> const & 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,b> const & lhs,
indexing_iterator<C,b> const & 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,b> const & lhs,
indexing_iterator<C,b> const & 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,b> const & lhs,
indexing_iterator<C,b> const & 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,b> const & lhs,
indexing_iterator<C,b> const & 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,b> const & lhs,
indexing_iterator<C,b> const & 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:
trdiff_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()
);
}
value_type & operator[] ( std::size_t i ) {
assert( i < 3 );
return ( (*this).*proxy() );
}
typedef indexing_iterator<point> iterator;
iterator begin ( void ) {
return ( iterator( *this, 0 ) );
}
iterator end ( void ) {
return ( iterator( *this, 3 ) );
}
typedef indexing_iterator<point const> const_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