]> git.lyx.org Git - lyx.git/blobdiff - boost/boost/operators.hpp
typos
[lyx.git] / boost / boost / operators.hpp
index bd571ec03d986f9b58713876fe7af6466f2fefa3..fbba602384e1f637cfe256ca9546066def7cf4c3 100644 (file)
@@ -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;
 
 #include <boost/config.hpp>
 #include <boost/iterator.hpp>
+#include <boost/detail/workaround.hpp>
 
 #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 <class T, class U, class B = ::boost::detail::empty_base>
-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 <class T, class B = ::boost::detail::empty_base>
-struct multipliable1 : B
-{
-     friend T operator*(T x, const T& y) { return x *= y; }
-};
-
-template <class T, class U, class B = ::boost::detail::empty_base>
-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 <class T, class B = ::boost::detail::empty_base>
-struct addable1 : B
-{
-     friend T operator+(T x, const T& y) { return x += y; }
-};
-
-template <class T, class U, class B = ::boost::detail::empty_base>
-struct subtractable2 : B
-{
-     friend T operator-(T x, const U& y) { return x -= y; }
-};
-
-template <class T, class U, class B = ::boost::detail::empty_base>
-struct subtractable2_left : B
-{
-  friend T operator-(const U& x, const T& y)
-    { T result(x); return result -= y; }
-};
-
-template <class T, class B = ::boost::detail::empty_base>
-struct subtractable1 : B
-{
-     friend T operator-(T x, const T& y) { return x -= y; }
-};
-
-template <class T, class U, class B = ::boost::detail::empty_base>
-struct dividable2 : B
-{
-     friend T operator/(T x, const U& y) { return x /= y; }
-};
-
-template <class T, class U, class B = ::boost::detail::empty_base>
-struct dividable2_left : B
-{
-  friend T operator/(const U& x, const T& y)
-    { T result(x); return result /= y; }
-};
-
-template <class T, class B = ::boost::detail::empty_base>
-struct dividable1 : B
-{
-     friend T operator/(T x, const T& y) { return x /= y; }
-};
-
-template <class T, class U, class B = ::boost::detail::empty_base>
-struct modable2 : B
-{
-     friend T operator%(T x, const U& y) { return x %= y; }
-};
-
-template <class T, class U, class B = ::boost::detail::empty_base>
-struct modable2_left : B
-{
-  friend T operator%(const U& x, const T& y)
-    { T result(x); return result %= y; }
-};
-
-template <class T, class B = ::boost::detail::empty_base>
-struct modable1 : B
-{
-     friend T operator%(T x, const T& y) { return x %= y; }
-};
-
-template <class T, class U, class B = ::boost::detail::empty_base>
-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 <class T, class B = ::boost::detail::empty_base>
-struct xorable1 : B
-{
-     friend T operator^(T x, const T& y) { return x ^= y; }
-};
-
-template <class T, class U, class B = ::boost::detail::empty_base>
-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 <class T, class B = ::boost::detail::empty_base>
-struct andable1 : B
-{
-     friend T operator&(T x, const T& y) { return x &= y; }
-};
-
-template <class T, class U, class B = ::boost::detail::empty_base>
-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 <class T, class B = ::boost::detail::empty_base>
-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 <class T, class U, class B = ::boost::detail::empty_base>            \
+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 <class T, class B = ::boost::detail::empty_base>                     \
+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 <class T, class U, class B = ::boost::detail::empty_base>  \
+struct NAME##2 : B                                                  \
+{                                                                   \
+  friend T operator OP( const T& lhs, const U& rhs )                \
+    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                    \
+};                                                                  \
+                                                                    \
+template <class T, class U, class B = ::boost::detail::empty_base>  \
+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 <class T, class B = ::boost::detail::empty_base>           \
+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 <class T, class U, class B = ::boost::detail::empty_base>            \
+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 <class T, class B = ::boost::detail::empty_base>                     \
+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 <class T, class U, class B = ::boost::detail::empty_base>      \
+struct NAME##2 : B                                                      \
+{                                                                       \
+  friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
+};                                                                      \
+                                                                        \
+template <class T, class U, class B = ::boost::detail::empty_base>      \
+struct BOOST_OPERATOR2_LEFT(NAME) : B                                   \
+{                                                                       \
+  friend T operator OP( const U& lhs, const T& rhs )                    \
+    { return T( lhs ) OP##= rhs; }                                      \
+};                                                                      \
+                                                                        \
+template <class T, class B = ::boost::detail::empty_base>               \
+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 <class T, class U, class B = ::boost::detail::empty_base>
-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 <class T, class B = ::boost::detail::empty_base>
-struct left_shiftable1 : B
-{
-     friend T operator<<(T x, const T& y) { return x <<= y; }
+#define BOOST_BINARY_OPERATOR( NAME, OP )                                     \
+template <class T, class U, class B = ::boost::detail::empty_base>            \
+struct NAME##2 : B                                                            \
+{                                                                             \
+  friend T operator OP( const T& lhs, const U& rhs )                          \
+    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
+};                                                                            \
+                                                                              \
+template <class T, class B = ::boost::detail::empty_base>                     \
+struct NAME##1 : B                                                            \
+{                                                                             \
+  friend T operator OP( const T& lhs, const T& rhs )                          \
+    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
 };
 
-template <class T, class U, class B = ::boost::detail::empty_base>
-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 <class T, class B = ::boost::detail::empty_base>
-struct right_shiftable1 : B
-{
-     friend T operator>>(T x, const T& y) { return x >>= y; }
+#define BOOST_BINARY_OPERATOR( NAME, OP )                                     \
+template <class T, class U, class B = ::boost::detail::empty_base>            \
+struct NAME##2 : B                                                            \
+{                                                                             \
+  friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; }       \
+};                                                                            \
+                                                                              \
+template <class T, class B = ::boost::detail::empty_base>                     \
+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 <class T, class U, class B = ::boost::detail::empty_base>
 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<class T> 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<class T> 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<class T> 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<class T> 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)                           \