1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
namespace toy
{
void swap( vector& a, vector& b ) { a.swap(b) ; }
// "comparing two floating-point numbers is harder than it looks
// if your goal is to meet the C++ order-relation requirements.
// The most straightforward strategy for defining comparison on
// floating-point numbers that might include NaN is to decide
// either that every NaN is "less than" every other number
// or "greater than" every other number." - Koenig
namespace detail
{
struct less
{
bool operator() ( double a, double b ) const noexcept
{
if( std::isnan(b) ) return !std::isnan(a);
else return a < b ; // crude (to be refined)
}
};
struct eq
{
bool operator() ( double a, double b ) const noexcept
{
if( std::isnan(a) ) return std::isnan(b);
else return a == b ; // crude (to be refined)
}
};
}
bool operator== ( const vector& a, const vector& b ) noexcept
{ return std::equal( a.begin(), a.end(), b.begin(), b.end(), detail::eq{} ) ; }
bool operator< ( const vector& a, const vector& b ) noexcept
{ return std::lexicographical_compare( a.begin(), a.end(), b.begin(), b.end(), detail::less{} ) ; }
bool operator!= ( const vector& a, const vector& b ) noexcept { return !(a==b) ; }
bool operator> ( const vector& a, const vector& b ) noexcept { return b<a ; }
bool operator<= ( const vector& a, const vector& b ) noexcept { return !(b<a) ; }
bool operator>= ( const vector& a, const vector& b ) noexcept { return !(a<b) ; }
// canonical overloads of binary arithmetic operators
// see 'Binary arithmetic operators' in http://en.cppreference.com/w/cpp/language/operators
template < typename T >
typename std::enable_if< std::is_arithmetic<T>::value, vector >::type operator+ ( vector vec, T value )
{ return vec += value ; }
template < typename T >
typename std::enable_if< std::is_arithmetic<T>::value, vector >::type operator+ ( T value, const vector& vec )
{ return vec + value ; }
template < typename T >
typename std::enable_if< std::is_arithmetic<T>::value, vector >::type operator- ( vector vec, T value )
{ return vec -= value ; }
template < typename T >
typename std::enable_if< std::is_arithmetic<T>::value, vector >::type operator* ( vector vec, T value )
{ return vec *= value ; }
template < typename T >
typename std::enable_if< std::is_arithmetic<T>::value, vector >::type operator* ( T value, const vector& vec )
{ return vec * value ; }
template < typename T >
typename std::enable_if< std::is_arithmetic<T>::value, vector >::type operator/ ( vector vec, T value )
{ return vec /= value ; }
}
int main()
{
toy::vector a { 1.2, 3,4, 5.6, 7.8, 9.1 } ;
auto b = a ;
std::cout << std::boolalpha << (a==b) << '\n' ;
a = b ;
std::cout << std::boolalpha << (a==b) << '\n' ;
b = std::move(a) ;
for( auto v : 21.3 * b ) std::cout << v << ' ' ;
std::cout << '\n' ;
}
|