[libsigc++2] Fix comma operator in lambda expressions.



commit 91e9495ecdef8cc314c695ab8f7db3dc5c0d6c73
Author: Andris Pavenis <andris pavenis iki fi>
Date:   Thu Sep 20 18:33:47 2012 +0200

    Fix comma operator in lambda expressions.
    
    * sigc++/adaptors/lambda/macros/operator.h.m4: Add lambda_action<>
    specialization for comma operator (operator,()).
    * tests/test_cpp11_lambda.cc:
    * tests/test_lambda.cc: Add a test case for the comma operator. Bug #342911.

 ChangeLog                                   |    9 +++++++++
 sigc++/adaptors/lambda/macros/operator.h.m4 |   22 ++++++++++++++++++++++
 tests/test_cpp11_lambda.cc                  |   13 ++++++++++++-
 tests/test_lambda.cc                        |    8 ++++++++
 4 files changed, 51 insertions(+), 1 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 3a64a8e..5458b90 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-09-20  Andris Pavenis  <andris pavenis iki fi>
+
+	Fix comma operator in lambda expressions.
+
+	* sigc++/adaptors/lambda/macros/operator.h.m4: Add lambda_action<>
+	specialization for comma operator (operator,()).
+	* tests/test_cpp11_lambda.cc:
+	* tests/test_lambda.cc: Add a test case for the comma operator. Bug #342911.
+
 2012-09-19  Kjell Ahlstedt  <kjell ahlstedt bredband net>
 
 	Add SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE.
diff --git a/sigc++/adaptors/lambda/macros/operator.h.m4 b/sigc++/adaptors/lambda/macros/operator.h.m4
index d97a2e5..593afeb 100644
--- a/sigc++/adaptors/lambda/macros/operator.h.m4
+++ b/sigc++/adaptors/lambda/macros/operator.h.m4
@@ -128,6 +128,26 @@ operator $2 (const T_arg1& a1, const lambda<T_arg2>& a2)
 
 divert(0)dnl
 ])
+define([LAMBDA_OPERATOR_COMMA],[dnl
+divert(1)dnl
+template <>
+struct lambda_action<$1 >
+{
+  template <class T_arg1, class T_arg2>
+  static typename lambda_action_deduce_result_type<$1, T_arg1, T_arg2>::type
+  do_action(T_arg1 _A_1, T_arg2 _A_2)
+    { return (void)_A_1 $2 _A_2; }
+};
+
+divert(2)dnl
+// Operators for lambda action $1. For comma we require that both arguments needs to be of type lamdba
+template <class T_arg1, class T_arg2>
+lambda<lambda_operator<$1, T_arg1, T_arg2> >
+operator $2 (const lambda<T_arg1>& a1, const lambda<T_arg2>& a2)
+{ typedef lambda_operator<$1, T_arg1, T_arg2> operator_type;
+  return lambda<operator_type>(operator_type(a1.value_,a2.value_)); }
+divert(0)dnl
+])
 define([LAMBDA_OPERATOR_UNARY],[dnl
 divert(1)dnl
 template <>
@@ -271,6 +291,7 @@ struct dereference {};
 struct reinterpret_ {};
 struct static_ {};
 struct dynamic_ {};
+struct comma {};
 
 template <class T_action, class T_test1, class T_test2>
 struct lambda_action_deduce_result_type
@@ -344,6 +365,7 @@ LAMBDA_OPERATOR(bitwise_assign<rightshift>,>>=)dnl
 LAMBDA_OPERATOR(bitwise_assign<and_>,&=)dnl
 LAMBDA_OPERATOR(bitwise_assign<or_>,|=)dnl
 LAMBDA_OPERATOR(bitwise_assign<xor_>,^=)dnl
+LAMBDA_OPERATOR_COMMA(comma,[,])dnl
 divert(1)dnl
 template <>
 struct lambda_action<other<subscript> >
diff --git a/tests/test_cpp11_lambda.cc b/tests/test_cpp11_lambda.cc
index dac825b..c94c8ca 100644
--- a/tests/test_cpp11_lambda.cc
+++ b/tests/test_cpp11_lambda.cc
@@ -49,7 +49,7 @@
 #include <iostream>
 #include <sstream>
 #include <functional>
-#include <stdlib.h>
+#include <cstdlib>
 #include <sigc++/functors/functors.h>
 #include <sigc++/bind.h>
 #include <sigc++/reference_wrapper.h>
@@ -239,6 +239,17 @@ int main()
   result_stream << ([] (int* x, int y) -> int { *x = y; return *x; }(&a,1));
   check_result("1");
 
+  // Comma operator, https://bugzilla.gnome.org/show_bug.cgi?id=342911
+  a = -1;
+  int b = -1;
+  int c = -1;
+  //std::cout << "(var(c) = (var(a) = _1, var(b) = _2))(2,3): "
+  //          << (sigc::var(c) = (sigc::var(a) = _1, sigc::var(b) = _2))(2,3);
+  //std::cout << "; a: " << a << "; b: " << b << "; c: " << c << std::endl;
+  result_stream << ([&a,&b,&c](int x, int y) -> int { return c = (a = x, b = y); }(2,3));
+  result_stream << " " << a << " " << b << " " << c;
+  check_result("3 2 3 3");
+
   // c++ restrictions:
   // - ref() must be used to indicate that the value shall not be copied
   // - constant() is used to create a lambda and delay execution of "std::cout << 1"
diff --git a/tests/test_lambda.cc b/tests/test_lambda.cc
index c8a7e72..fd844ec 100644
--- a/tests/test_lambda.cc
+++ b/tests/test_lambda.cc
@@ -85,6 +85,14 @@ int main()
   std::cout << "(_1[_2])    (&a,0): " << (_1[_2])    (&a,0)   << std::endl;
   std::cout << "(*_1=_2)    (&a,1): " << (*_1=_2)    (&a,1)   << std::endl;
 
+  // Comma operator, https://bugzilla.gnome.org/show_bug.cgi?id=342911
+  a = -1;
+  int b = -1;
+  int c = -1;
+  std::cout << "(var(c) = (var(a) = _1, var(b) = _2))(2,3): "
+            << (sigc::var(c) = (sigc::var(a) = _1, sigc::var(b) = _2))(2,3);
+  std::cout << "; a: " << a << "; b: " << b << "; c: " << c << std::endl;
+
        // c++ restrictions:
        // - ref() must be used to indicate that the value shall not be copied
        // - constant() is used to create a lambda and delay execution of "std::cout << 1"



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]