X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=boost%2Fboost%2Foperators.hpp;h=fbba602384e1f637cfe256ca9546066def7cf4c3;hb=b01a9dc187d9cd396a57463ad27511379dcdc9cd;hp=bd571ec03d986f9b58713876fe7af6466f2fefa3;hpb=59b6a4701a8d2b5155af08cf758b4ca120201282;p=lyx.git diff --git a/boost/boost/operators.hpp b/boost/boost/operators.hpp index bd571ec03d..fbba602384 100644 --- a/boost/boost/operators.hpp +++ b/boost/boost/operators.hpp @@ -1,14 +1,16 @@ // Boost operators.hpp header file ----------------------------------------// -// (C) Copyright David Abrahams, Jeremy Siek, and Daryle Walker 1999-2001. -// Permission to copy, use, modify, sell and distribute this software is -// granted provided this copyright notice appears in all copies. This -// software is provided "as is" without express or implied warranty, and -// with no claim as to its suitability for any purpose. +// (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) -// See http://www.boost.org for most recent version including documentation. +// See http://www.boost.org/libs/utility/operators.htm for documentation. // Revision History +// 21 Oct 02 Modified implementation of operators to allow compilers with a +// correct named return value optimization (NRVO) to produce optimal +// code. (Daniel Frey) // 02 Dec 01 Bug fixed in random_access_iteratable. (Helmut Zeisel) // 28 Sep 01 Factored out iterator operator groups. (Daryle Walker) // 27 Aug 01 'left' form for non commutative operators added; @@ -75,9 +77,10 @@ #include #include +#include #if defined(__sgi) && !defined(__GNUC__) -#pragma set woff 1234 +# pragma set woff 1234 #endif #if defined(BOOST_MSVC) @@ -149,127 +152,112 @@ struct equality_comparable1 : B friend bool operator!=(const T& x, const T& y) { return !(x == y); } }; -template -struct multipliable2 : B -{ - friend T operator*(T x, const U& y) { return x *= y; } - friend T operator*(const U& y, T x) { return x *= y; } -}; - -template -struct multipliable1 : B -{ - friend T operator*(T x, const T& y) { return x *= y; } -}; - -template -struct addable2 : B -{ - friend T operator+(T x, const U& y) { return x += y; } - friend T operator+(const U& y, T x) { return x += y; } -}; - -template -struct addable1 : B -{ - friend T operator+(T x, const T& y) { return x += y; } -}; - -template -struct subtractable2 : B -{ - friend T operator-(T x, const U& y) { return x -= y; } -}; - -template -struct subtractable2_left : B -{ - friend T operator-(const U& x, const T& y) - { T result(x); return result -= y; } -}; - -template -struct subtractable1 : B -{ - friend T operator-(T x, const T& y) { return x -= y; } -}; - -template -struct dividable2 : B -{ - friend T operator/(T x, const U& y) { return x /= y; } -}; - -template -struct dividable2_left : B -{ - friend T operator/(const U& x, const T& y) - { T result(x); return result /= y; } -}; - -template -struct dividable1 : B -{ - friend T operator/(T x, const T& y) { return x /= y; } -}; - -template -struct modable2 : B -{ - friend T operator%(T x, const U& y) { return x %= y; } -}; - -template -struct modable2_left : B -{ - friend T operator%(const U& x, const T& y) - { T result(x); return result %= y; } -}; - -template -struct modable1 : B -{ - friend T operator%(T x, const T& y) { return x %= y; } -}; - -template -struct xorable2 : B -{ - friend T operator^(T x, const U& y) { return x ^= y; } - friend T operator^(const U& y, T x) { return x ^= y; } -}; - -template -struct xorable1 : B -{ - friend T operator^(T x, const T& y) { return x ^= y; } -}; - -template -struct andable2 : B -{ - friend T operator&(T x, const U& y) { return x &= y; } - friend T operator&(const U& y, T x) { return x &= y; } -}; - -template -struct andable1 : B -{ - friend T operator&(T x, const T& y) { return x &= y; } -}; - -template -struct orable2 : B -{ - friend T operator|(T x, const U& y) { return x |= y; } - friend T operator|(const U& y, T x) { return x |= y; } -}; - -template -struct orable1 : B -{ - friend T operator|(T x, const T& y) { return x |= y; } -}; +// A macro which produces "name_2left" from "name". +#define BOOST_OPERATOR2_LEFT(name) name##2##_##left + +// NRVO-friendly implementation (contributed by Daniel Frey) ---------------// + +#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) + +// This is the optimal implementation for ISO/ANSI C++, +// but it requires the compiler to implement the NRVO. +// If the compiler has no NRVO, this is the best symmetric +// implementation available. + +#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \ +template \ +struct NAME##2 : B \ +{ \ + friend T operator OP( const T& lhs, const U& rhs ) \ + { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ + friend T operator OP( const U& lhs, const T& rhs ) \ + { T nrv( rhs ); nrv OP##= lhs; return nrv; } \ +}; \ + \ +template \ +struct NAME##1 : B \ +{ \ + friend T operator OP( const T& lhs, const T& rhs ) \ + { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ +}; + +#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \ +template \ +struct NAME##2 : B \ +{ \ + friend T operator OP( const T& lhs, const U& rhs ) \ + { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ +}; \ + \ +template \ +struct BOOST_OPERATOR2_LEFT(NAME) : B \ +{ \ + friend T operator OP( const U& lhs, const T& rhs ) \ + { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ +}; \ + \ +template \ +struct NAME##1 : B \ +{ \ + friend T operator OP( const T& lhs, const T& rhs ) \ + { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ +}; + +#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) + +// For compilers without NRVO the following code is optimal, but not +// symmetric! Note that the implementation of +// BOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide +// optimization opportunities to the compiler :) + +#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \ +template \ +struct NAME##2 : B \ +{ \ + friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ + friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \ +}; \ + \ +template \ +struct NAME##1 : B \ +{ \ + friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ +}; + +#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \ +template \ +struct NAME##2 : B \ +{ \ + friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ +}; \ + \ +template \ +struct BOOST_OPERATOR2_LEFT(NAME) : B \ +{ \ + friend T operator OP( const U& lhs, const T& rhs ) \ + { return T( lhs ) OP##= rhs; } \ +}; \ + \ +template \ +struct NAME##1 : B \ +{ \ + friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ +}; + +#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) + +BOOST_BINARY_OPERATOR_COMMUTATIVE( multipliable, * ) +BOOST_BINARY_OPERATOR_COMMUTATIVE( addable, + ) +BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( subtractable, - ) +BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( dividable, / ) +BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( modable, % ) +BOOST_BINARY_OPERATOR_COMMUTATIVE( xorable, ^ ) +BOOST_BINARY_OPERATOR_COMMUTATIVE( andable, & ) +BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | ) + +#undef BOOST_BINARY_OPERATOR_COMMUTATIVE +#undef BOOST_BINARY_OPERATOR_NON_COMMUTATIVE +#undef BOOST_OPERATOR2_LEFT // incrementable and decrementable contributed by Jeremy Siek @@ -278,9 +266,9 @@ struct incrementable : B { friend T operator++(T& x, int) { - incrementable_type tmp(x); + incrementable_type nrv(x); ++x; - return tmp; + return nrv; } private: // The use of this typedef works around a Borland bug typedef T incrementable_type; @@ -291,9 +279,9 @@ struct decrementable : B { friend T operator--(T& x, int) { - decrementable_type tmp(x); + decrementable_type nrv(x); --x; - return tmp; + return nrv; } private: // The use of this typedef works around a Borland bug typedef T decrementable_type; @@ -320,31 +308,47 @@ struct indexable : B }; // More operator classes (contributed by Daryle Walker) --------------------// +// (NRVO-friendly implementation contributed by Daniel Frey) ---------------// -template -struct left_shiftable2 : B -{ - friend T operator<<(T x, const U& y) { return x <<= y; } -}; +#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) -template -struct left_shiftable1 : B -{ - friend T operator<<(T x, const T& y) { return x <<= y; } +#define BOOST_BINARY_OPERATOR( NAME, OP ) \ +template \ +struct NAME##2 : B \ +{ \ + friend T operator OP( const T& lhs, const U& rhs ) \ + { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ +}; \ + \ +template \ +struct NAME##1 : B \ +{ \ + friend T operator OP( const T& lhs, const T& rhs ) \ + { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ }; -template -struct right_shiftable2 : B -{ - friend T operator>>(T x, const U& y) { return x >>= y; } -}; +#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) -template -struct right_shiftable1 : B -{ - friend T operator>>(T x, const T& y) { return x >>= y; } +#define BOOST_BINARY_OPERATOR( NAME, OP ) \ +template \ +struct NAME##2 : B \ +{ \ + friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ +}; \ + \ +template \ +struct NAME##1 : B \ +{ \ + friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ }; +#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) + +BOOST_BINARY_OPERATOR( left_shiftable, << ) +BOOST_BINARY_OPERATOR( right_shiftable, >> ) + +#undef BOOST_BINARY_OPERATOR + template struct equivalent2 : B { @@ -670,7 +674,7 @@ struct random_access_iteratable // Here's where we put it all together, defining the xxxx forms of the templates // in namespace boost. We also define specializations of is_chained_base<> for // the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as -// neccessary. +// necessary. // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION @@ -695,7 +699,7 @@ template struct is_chained_base { } // namespace boost -// Import a 4-type-argument operator template into boost (if neccessary) and +// Import a 4-type-argument operator template into boost (if necessary) and // provide a specialization of 'is_chained_base<>' for it. # define BOOST_OPERATOR_TEMPLATE4(template_name4) \ BOOST_IMPORT_TEMPLATE4(template_name4) \ @@ -704,7 +708,7 @@ template struct is_chained_base { typedef ::boost::detail::true_t value; \ }; -// Import a 3-type-argument operator template into boost (if neccessary) and +// Import a 3-type-argument operator template into boost (if necessary) and // provide a specialization of 'is_chained_base<>' for it. # define BOOST_OPERATOR_TEMPLATE3(template_name3) \ BOOST_IMPORT_TEMPLATE3(template_name3) \ @@ -713,7 +717,7 @@ template struct is_chained_base { typedef ::boost::detail::true_t value; \ }; -// Import a 2-type-argument operator template into boost (if neccessary) and +// Import a 2-type-argument operator template into boost (if necessary) and // provide a specialization of 'is_chained_base<>' for it. # define BOOST_OPERATOR_TEMPLATE2(template_name2) \ BOOST_IMPORT_TEMPLATE2(template_name2) \ @@ -722,7 +726,7 @@ template struct is_chained_base { typedef ::boost::detail::true_t value; \ }; -// Import a 1-type-argument operator template into boost (if neccessary) and +// Import a 1-type-argument operator template into boost (if necessary) and // provide a specialization of 'is_chained_base<>' for it. # define BOOST_OPERATOR_TEMPLATE1(template_name1) \ BOOST_IMPORT_TEMPLATE1(template_name1) \