diff options
author | Kjell Ahlstedt <kjell.ahlstedt@bredband.net> | 2015-09-26 12:03:02 +0200 |
---|---|---|
committer | Kjell Ahlstedt <kjell.ahlstedt@bredband.net> | 2015-09-26 12:03:02 +0200 |
commit | 910a3e3044dfd78887019b469d592028ce8a2593 (patch) | |
tree | 78b11a8ceac52838f95e5f30306719f66c88f5cb | |
parent | d9aea78124604316fd2c6749f15f9bc98c6b5cf0 (diff) | |
download | sigc++-910a3e3044dfd78887019b469d592028ce8a2593.tar.gz |
Recreate adaptors/lambda files necessary not to break ABI
* sigc++/adaptors/lambda/macros/base.h.m4:
* sigc++/adaptors/lambda/macros/lambda.cc.m4:
* sigc++/adaptors/lambda/macros/select.h.m4: Recreate these files.
* sigc++/Makefile.am:
* sigc++/filelist.am: Add the recreated lambda files.
Approximately a reversion of commit a259b4c7a1753dbc389ee467fa536339ec820223,
"Remove remaining parts of the sigc::lambda API."
Differences from an exact reversion: MSVC_Net files are not modified.
(Probably something ought to be changed in MSVC_Net2013.)
tests/Makefile.am is not modified-
is_base_and_derived<> is replaced by std::is_base_of<> in base.h.m4.
The extern declarations that were previously in select.h.m4 are moved to
lambda.cc.m4. Without them, sigc::_1 .. sigc::_7 are not included in
the .so file.
All code in the header files are inside #ifndef DOXYGEN_SHOULD_SKIP_THIS.
Bug #755550.
-rw-r--r-- | sigc++/Makefile.am | 14 | ||||
-rw-r--r-- | sigc++/adaptors/lambda/macros/base.h.m4 | 210 | ||||
-rw-r--r-- | sigc++/adaptors/lambda/macros/lambda.cc.m4 | 36 | ||||
-rw-r--r-- | sigc++/adaptors/lambda/macros/select.h.m4 | 77 | ||||
-rw-r--r-- | sigc++/filelist.am | 13 |
5 files changed, 345 insertions, 5 deletions
diff --git a/sigc++/Makefile.am b/sigc++/Makefile.am index 0c6b886..caa9e15 100644 --- a/sigc++/Makefile.am +++ b/sigc++/Makefile.am @@ -20,7 +20,7 @@ AUTOMAKE_OPTIONS = subdir-objects include $(srcdir)/filelist.am # Subdirectories needed also in the build dir -build_subdirs = functors +build_subdirs = functors adaptors/lambda dist_noinst_DATA = $(sigc_m4) @@ -35,7 +35,8 @@ libsigc_@SIGCXX_API_VERSION@_la_SOURCES = \ trackable.cc \ connection.cc \ functors/slot.cc \ - functors/slot_base.cc + functors/slot_base.cc \ + adaptors/lambda/lambda.cc EXTRA_libsigc_@SIGCXX_API_VERSION@_la_SOURCES = $(sigc_built_cc) @@ -61,6 +62,15 @@ signal.cc: \ functors/mem_fun.h \ functors/functor_trait.h +adaptors/lambda/lambda.cc: \ + adaptors/lambda/select.h \ + adaptors/lambda/base.h \ + adaptors/adaptor_trait.h \ + adaptors/deduce_result_type.h \ + functors/ptr_fun.h \ + functors/mem_fun.h \ + functors/functor_trait.h + functors/slot.cc: \ functors/slot.h \ functors/slot_base.h \ diff --git a/sigc++/adaptors/lambda/macros/base.h.m4 b/sigc++/adaptors/lambda/macros/base.h.m4 new file mode 100644 index 0000000..083bf85 --- /dev/null +++ b/sigc++/adaptors/lambda/macros/base.h.m4 @@ -0,0 +1,210 @@ +dnl Copyright 2002, The libsigc++ Development Team +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License, or (at your option) any later version. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +divert(-1) +include(template.macros.m4) + +define([LAMBDA_DO],[dnl + template <LOOP(class T_arg%1, $1)> + typename deduce_result_type<LOOP(T_arg%1,$1)>::type + operator ()(LOOP(T_arg%1 _A_%1, $1)) const + { return value_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LOOP(_P_(T_arg%1), $1)> + (LOOP(_A_%1, $1)); + } + + #ifndef SIGC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD + template <LOOP(class T_arg%1, $1)> + typename deduce_result_type<LOOP(T_arg%1,$1)>::type + sun_forte_workaround(LOOP(T_arg%1 _A_%1, $1)) const + { return value_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LOOP(_P_(T_arg%1), $1)> + (LOOP(_A_%1, $1)); + } + #endif //SIGC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD + +])dnl +define([LAMBDA_DO_VALUE],[dnl + template <LOOP(class T_arg%1, $1)> + result_type operator ()(LOOP(T_arg%1, $1)) const + { return value_; } + + #ifndef SIGC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD + template <LOOP(class T_arg%1, $1)> + result_type sun_forte_workaround(LOOP(T_arg%1, $1)) const + { return value_; } + #endif //SIGC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD + +])dnl + +divert(0)dnl +#ifndef _SIGC_LAMBDA_BASE_HPP_ +#define _SIGC_LAMBDA_BASE_HPP_ +#include <sigc++/adaptors/adaptor_trait.h> +#include <sigc++/reference_wrapper.h> +#include <type_traits> + +_DEPRECATE_IFDEF_START + +namespace sigc { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +// libsigc++'s lambda functions have been removed from the API. +// Some code must be kept until we can break ABI. +/** @defgroup lambdas Lambdas + * libsigc++ ships with basic lambda functionality and the sigc::group adaptor, + * which uses lambdas to transform a functor's parameter list. + * + * The lambda selectors sigc::_1, sigc::_2, ..., sigc::_7 are used to select the + * first, second, ..., seventh argument from a list. + * + * @par Examples: + * @code + * std::cout << sigc::_1(10,20,30); // returns 10 + * std::cout << sigc::_2(10,20,30); // returns 20 + * @endcode + * + * Operators are defined so that, for example, lambda selectors can be used as + * placeholders in arithmetic expressions. + * + * @par Examples: + * @code + * std::cout << (sigc::_1 + 5)(3); // returns (3 + 5) + * std::cout << (sigc::_1 * sigc::_2)(7,10); // returns (7 * 10) + * @endcode + * + * If your compiler supports C++11 lambda expressions, they are often a good + * alternative to libsigc++'s lambda expressions. The following examples are + * equivalent to the previous ones. + * @code + * [[]] (int x, int, int) -> int { return x; }(10,20,30); // returns 10 + * [[]] (int, int y, int) -> int { return y; }(10,20,30); // returns 20 + * [[]] (int x) -> int { return x + 5; }(3); // returns (3 + 5) + * [[]] (int x, int y) -> int { return x * y; }(7,10); // returns (7 * 10) + * @endcode + * + * @deprecated Use C++11 lambda expressions or %std::bind() instead. + */ + +/** A hint to the compiler. + * All lambda types publically inherit from this hint. + * + * @deprecated Use C++11 lambda expressions instead. + * + * @ingroup lambdas + */ +struct lambda_base : public adaptor_base {}; + +// Forward declaration of lambda. +template <class T_type> struct lambda; + +namespace internal { + +/** Abstracts lambda functionality. + * Objects of this type store a value that may be of type lambda itself. + * In this case, operator()() executes the lambda (a lambda is always a functor at the same time). + * Otherwise, operator()() simply returns the stored value. + * + * @deprecated Use C++11 lambda expressions instead. + * + * @ingroup lambdas + */ +template <class T_type, bool I_islambda = std::is_base_of<lambda_base, T_type>::value> struct lambda_core; + +/** Abstracts lambda functionality (template specialization for lambda values). + * + * @deprecated Use C++11 lambda expressions instead. + * + * @ingroup lambdas + */ +template <class T_type> +struct lambda_core<T_type, true> : public lambda_base +{ + template <LOOP(class T_arg%1=void,CALL_SIZE)> + struct deduce_result_type + { typedef typename T_type::template deduce_result_type<LOOP(_P_(T_arg%1),CALL_SIZE)>::type type; }; + typedef typename T_type::result_type result_type; + typedef T_type lambda_type; + + result_type + operator()() const; + +FOR(1,CALL_SIZE,[[LAMBDA_DO(%1)]])dnl + lambda_core() {} + + explicit lambda_core(const T_type& v) + : value_(v) {} + + T_type value_; +}; + + +} /* namespace internal */ + + +// forward declarations for lambda operators other<subscript> and other<assign> +template <class T_type> +struct other; +struct subscript; +struct assign; + +template <class T_action, class T_type1, class T_type2> +struct lambda_operator; + +template <class T_type> +struct unwrap_lambda_type; + +/** Lambda type. + * Objects of this type store a value that may be of type lambda itself. + * In this case, operator()() executes the lambda (a lambda is always a functor at the same time). + * Otherwise, operator()() simply returns the stored value. + * The assign and subscript operators are defined to return a lambda operator. + * + * @deprecated Use C++11 lambda expressions instead. + * + * @ingroup lambdas + */ +template <class T_type> +struct lambda : public internal::lambda_core<T_type> +{ + typedef lambda<T_type> self; + + lambda() + {} + + lambda(typename type_trait<T_type>::take v) + : internal::lambda_core<T_type>(v) + {} + + // operators for other<subscript> + template <class T_arg> + lambda<lambda_operator<other<subscript>, self, typename unwrap_lambda_type<T_arg>::type> > + operator [[]] (const T_arg& a) const + { typedef lambda_operator<other<subscript>, self, typename unwrap_lambda_type<T_arg>::type> lambda_operator_type; + return lambda<lambda_operator_type>(lambda_operator_type(this->value_, unwrap_lambda_value(a))); } + + // operators for other<assign> + template <class T_arg> + lambda<lambda_operator<other<assign>, self, typename unwrap_lambda_type<T_arg>::type> > + operator = (const T_arg& a) const + { typedef lambda_operator<other<assign>, self, typename unwrap_lambda_type<T_arg>::type> lambda_operator_type; + return lambda<lambda_operator_type>(lambda_operator_type(this->value_, unwrap_lambda_value(a))); } +}; +#endif // DOXYGEN_SHOULD_SKIP_THIS + +} /* namespace sigc */ + +_DEPRECATE_IFDEF_END + +#endif /* _SIGC_LAMBDA_BASE_HPP_ */ diff --git a/sigc++/adaptors/lambda/macros/lambda.cc.m4 b/sigc++/adaptors/lambda/macros/lambda.cc.m4 new file mode 100644 index 0000000..f9fa909 --- /dev/null +++ b/sigc++/adaptors/lambda/macros/lambda.cc.m4 @@ -0,0 +1,36 @@ +dnl Copyright 2002, The libsigc++ Development Team +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License, or (at your option) any later version. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +divert(-1) +include(template.macros.m4) +divert(0)dnl +#include <sigc++/adaptors/lambda/select.h> + +_DEPRECATE_IFDEF_START + +namespace sigc { + +// sigc::_1 .. sigc::_7 must be kept until we can break ABI. +// See https://bugzilla.gnome.org/show_bug.cgi?id=755550 +// The extern declarations have been moved from select.h, to keep them out of the API. +// Without them the const sigc::_1 .. sigc::_7 would be local to this .cc file. +FOR(1,CALL_SIZE,[[extern SIGC_API const lambda<internal::lambda_select%1> _%1; +]]) +FOR(1,CALL_SIZE,[[const lambda<internal::lambda_select%1> _%1; +]]) +} /* namespace sigc */ + +_DEPRECATE_IFDEF_END diff --git a/sigc++/adaptors/lambda/macros/select.h.m4 b/sigc++/adaptors/lambda/macros/select.h.m4 new file mode 100644 index 0000000..ab512a6 --- /dev/null +++ b/sigc++/adaptors/lambda/macros/select.h.m4 @@ -0,0 +1,77 @@ +dnl Copyright 2002, The libsigc++ Development Team +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License, or (at your option) any later version. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +divert(-1) +include(template.macros.m4) + +dnl +dnl Macros to make select arguments +define([LAMBDA_SELECT_DO],[dnl + template <LOOP(class T_arg%1, $2)> +dnl T_arg$1 operator ()(LOOP(T_arg%1 _A_%1, $2)) const { return _A_$1; } + T_arg$1 operator ()(LIST(FOR(1,eval($1-1),[T_arg%1,]),T_arg$1 _A_$1,FOR(eval($1+1),$2,[T_arg%1,]))) const { return _A_$1; } + + #ifndef SIGC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD + template <LOOP(class T_arg%1, $2)> + //Does not work: T_arg$1 sun_forte_workaround(LOOP(T_arg%1 _A_%1, $2)) const { return operator()( LOOP(_A_%1, $2) ); } + T_arg$1 sun_forte_workaround(LIST(FOR(1,eval($1-1),[T_arg%1,]),T_arg$1 _A_$1,FOR(eval($1+1),$2,[T_arg%1,]))) const { return _A_$1; } + #endif + +]) +define([LAMBDA_SELECT],[dnl +struct lambda_select$1 : public lambda_base +{ + template <LOOP(class T_arg%1=void,$2)> + struct deduce_result_type + { typedef T_arg$1 type; }; + typedef void result_type; // no operator ()() overload + + void operator ()() const; // not implemented +FOR($1, $2,[[LAMBDA_SELECT_DO($1,%1)]])dnl +}; + +]) +define([LAMBDA_SELECTOR],[dnl +/** Lambda selector. + * + * @deprecated Use C++11 lambda expressions or %std::bind() instead of libsigc++ lambdas and sigc::group(). + * + * @ingroup lambdas + */ +extern SIGC_API const lambda<internal::lambda_select$1> _$1; + +]) + +divert(0)dnl +#ifndef _SIGC_LAMBDA_SELECT_HPP_ +#define _SIGC_LAMBDA_SELECT_HPP_ +#include <sigc++/adaptors/lambda/base.h> + +_DEPRECATE_IFDEF_START + +namespace sigc { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +namespace internal { +FOR(1,CALL_SIZE,[[LAMBDA_SELECT(%1,CALL_SIZE)]])dnl +} /* namespace internal */ + +#endif // DOXYGEN_SHOULD_SKIP_THIS +} /* namespace sigc */ + +_DEPRECATE_IFDEF_END + +#endif /* _SIGC_LAMBDA_SELECT_HPP_ */ diff --git a/sigc++/filelist.am b/sigc++/filelist.am index 764e83f..9663ea8 100644 --- a/sigc++/filelist.am +++ b/sigc++/filelist.am @@ -34,17 +34,24 @@ adaptors_built_h = deduce_result_type.h adaptor_trait.h bind.h bind_return.h \ retype_return.h hide.h retype.h compose.h exception_catch.h \ track_obj.h +# Lambda (adaptors/lambda) +lambda_m4 = base.h.m4 select.h.m4 lambda.cc.m4 +lambda_built_cc = lambda.cc +lambda_built_h = base.h select.h # Combine all the above parts with right directories prefixed sigc_m4 = $(base_m4:%=macros/%) \ $(functors_m4:%=functors/macros/%) \ - $(adaptors_m4:%=adaptors/macros/%) + $(adaptors_m4:%=adaptors/macros/%) \ + $(lambda_m4:%=adaptors/lambda/macros/%) sigc_built_cc = $(base_built_cc) \ $(functors_built_cc:%=functors/%) \ - $(adaptors_built_cc:%=adaptors/%) + $(adaptors_built_cc:%=adaptors/%) \ + $(lambda_built_cc:%=adaptors/lambda/%) sigc_built_h = $(base_built_h) \ $(functors_built_h:%=functors/%) \ - $(adaptors_built_h:%=adaptors/%) + $(adaptors_built_h:%=adaptors/%) \ + $(lambda_built_h:%=adaptors/lambda/%) sigc_public_h = \ bind.h \ |