[libsigcplusplus] tuple_transform_each(): Allow this to be a constexpr.



commit 97df7e3637af7355b51db89e5ebf119742f23681
Author: Murray Cumming <murrayc murrayc com>
Date:   Tue Mar 8 19:10:30 2016 +0100

    tuple_transform_each(): Allow this to be a constexpr.

 sigc++/tuple-utils/tuple_transform_each.h |   10 ++++-
 tests/test_tuple_transform_each.cc        |   51 +++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 2 deletions(-)
---
diff --git a/sigc++/tuple-utils/tuple_transform_each.h b/sigc++/tuple-utils/tuple_transform_each.h
index 069e3a9..463925d 100644
--- a/sigc++/tuple-utils/tuple_transform_each.h
+++ b/sigc++/tuple-utils/tuple_transform_each.h
@@ -32,6 +32,7 @@ template <template <typename> class T_transformer, std::size_t size_from_index>
 struct tuple_transform_each_impl {
   // TODO: Avoid the need to pass t_original all the way into the recursion?
   template <typename T_current, typename T_original>
+  constexpr
   static decltype(auto)
   tuple_transform_each(T_current&& t, T_original& t_original) {
     //We use std::decay_t<> because tuple_size is not defined for references.
@@ -66,7 +67,9 @@ struct tuple_transform_each_impl {
 template <template <typename> class T_transformer>
 struct tuple_transform_each_impl<T_transformer, 1> {
   template <typename T_current, typename T_original>
-  static decltype(auto)
+  constexpr
+  static
+  decltype(auto)
   tuple_transform_each(T_current&& t, T_original& t_original) {
     //We use std::decay_t<> because tuple_size is not defined for references.
     constexpr auto size = std::tuple_size<std::decay_t<T_current>>::value;
@@ -89,7 +92,9 @@ struct tuple_transform_each_impl<T_transformer, 1> {
 template <template <typename> class T_transformer>
 struct tuple_transform_each_impl<T_transformer, 0> {
   template <typename T_current, typename T_original>
-  static decltype(auto)
+  constexpr
+  static
+  decltype(auto)
   tuple_transform_each(T_current&& t, T_original& /* t_original */) {
       //Do nothing because the tuple has no elements.
       return std::forward<T_current>(t);
@@ -103,6 +108,7 @@ struct tuple_transform_each_impl<T_transformer, 0> {
  * in the original tuple.
  */
 template <template <typename> class T_transformer, typename T>
+constexpr
 decltype(auto)
 tuple_transform_each(T&& t) {
   //We use std::decay_t<> because tuple_size is not defined for references.
diff --git a/tests/test_tuple_transform_each.cc b/tests/test_tuple_transform_each.cc
index 8830011..4474d8e 100644
--- a/tests/test_tuple_transform_each.cc
+++ b/tests/test_tuple_transform_each.cc
@@ -262,6 +262,55 @@ test_tuple_transform_each_empty_tuple() {
   sigc::internal::tuple_transform_each<transform_to_string>(t);
 }
 
+// The general template declaration.
+// We then provide specializations for each type,
+// so we can test having a different return value for each T_element_from type.
+template <class T_element_from>
+class transform_as_constexpr_to_something;
+
+// An int will be converted to a char:
+template <>
+class transform_as_constexpr_to_something<int> {
+public:
+  constexpr
+  static
+  char
+  transform(int from) {
+    return 'a' + from;
+  }
+};
+
+// A double will be converted to an int:
+template <>
+class transform_as_constexpr_to_something<const double> {
+public:
+  constexpr
+  static
+  int
+  transform(double from) {
+    return (int)from;
+  }
+};
+
+constexpr
+void
+test_tuple_transform_each_constexpr() {
+  constexpr auto t_original = std::make_tuple(1, (double)2.1f);
+  constexpr auto t_transformed =
+    sigc::internal::tuple_transform_each<transform_as_constexpr_to_something>(t_original);
+  constexpr auto t_expected = std::make_tuple('b', 2);
+
+  static_assert(std::tuple_size<decltype(t_transformed)>::value == 2,
+    "unexpected tuple_transform_each()ed tuple size.");
+
+  assert(std::get<0>(t_transformed) == 'b');
+  assert(std::get<1>(t_transformed) == 2);
+
+  static_assert(
+    std::is_same<decltype(t_transformed), decltype(t_expected)>::value,
+    "unexpected transform_each()ed tuple type");
+}
+
 int
 main() {
   test_tuple_transform_each_same_types();
@@ -276,5 +325,7 @@ main() {
 
   test_tuple_transform_each_empty_tuple();
 
+  test_tuple_transform_each_constexpr();
+
   return EXIT_SUCCESS;
 }


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