[glibmm/glibmm-2-54] Glib::Variant<std::tuple>: Don't use std::index_sequence from C++14
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm/glibmm-2-54] Glib::Variant<std::tuple>: Don't use std::index_sequence from C++14
- Date: Mon, 18 Sep 2017 15:00:54 +0000 (UTC)
commit 7f825b98c6ba261ffe1117ec80e3b150de424bcd
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date: Mon Sep 18 16:54:33 2017 +0200
Glib::Variant<std::tuple>: Don't use std::index_sequence from C++14
std::index_sequence and std::index_sequence_for are new in C++14,
but this version of glibmm requires only C++11.
The code that replaces std::index_sequence has been provided by
Jonathan Wakely <zilla kayari org>. Bug 787648
glib/src/variant.hg | 73 ++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 69 insertions(+), 4 deletions(-)
---
diff --git a/glib/src/variant.hg b/glib/src/variant.hg
index 5ec352b..f4503e2 100644
--- a/glib/src/variant.hg
+++ b/glib/src/variant.hg
@@ -29,6 +29,7 @@ _DEFS(glibmm,glib)
#include <tuple>
#include <stdexcept>
#include <typeinfo>
+#include <cstddef>
namespace Glib
{
@@ -1502,11 +1503,72 @@ const VariantType& Variant<std::tuple<Types...>>::variant_type()
return type;
}
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace detail
{
+// std::index_sequence and std::index_sequence_for are new in C++14,
+// but this version of glibmm requires only C++11.
+// The following code replaces std::index_sequence and std::index_sequence_for
+// until we can require C++14 support.
+// See https://bugzilla.gnome.org/show_bug.cgi?id=787648
+
+ /// Class template integer_sequence
+ template<typename T, T... Idx>
+ struct integer_sequence
+ {
+ typedef T value_type;
+ static constexpr std::size_t size() { return sizeof...(Idx); }
+ };
+
+ // Concatenates two integer_sequences.
+ template<typename Iseq1, typename Iseq2> struct iseq_cat;
+
+ template<typename T, std::size_t... Ind1, std::size_t... Ind2>
+ struct iseq_cat<integer_sequence<T, Ind1...>, integer_sequence<T, Ind2...>>
+ {
+ using type = integer_sequence<T, Ind1..., (Ind2 + sizeof...(Ind1))...>;
+ };
+
+ // Builds an integer_sequence<T, 0, 1, 2, ..., Num-1>.
+ template<typename T, std::size_t Num>
+ struct make_intseq
+ : iseq_cat<typename make_intseq<T, Num / 2>::type,
+ typename make_intseq<T, Num - Num / 2>::type>
+ { };
+
+ template<typename T>
+ struct make_intseq<T, 1>
+ {
+ typedef integer_sequence<T, 0> type;
+ };
+
+ template<typename T>
+ struct make_intseq<T, 0>
+ {
+ typedef integer_sequence<T> type;
+ };
+
+ /// Alias template make_integer_sequence
+ template<typename T, T Num>
+ using make_integer_sequence = typename make_intseq<T, Num>::type;
+
+ /// Alias template index_sequence
+ template<std::size_t... Idx>
+ using index_sequence = integer_sequence<std::size_t, Idx...>;
+
+ /// Alias template make_index_sequence
+ template<std::size_t Num>
+ using make_index_sequence = make_integer_sequence<std::size_t, Num>;
+
+ /// Alias template index_sequence_for
+ template<typename... Types>
+ using index_sequence_for = make_index_sequence<sizeof...(Types)>;
+
+// End of code that replaces std::index_sequence and std::index_sequence_for
+
template <class Tuple, std::size_t... Is>
void expand_tuple(std::vector<VariantBase> &variants, const Tuple & t,
- std::index_sequence<Is...>)
+ detail::index_sequence<Is...>)
{
using swallow = int[]; // ensures left to right order
auto expander = [&variants](const VariantBase &variant) -> int
@@ -1517,6 +1579,7 @@ void expand_tuple(std::vector<VariantBase> &variants, const Tuple & t,
(void)swallow {(expander(Variant<typename std::tuple_element<Is,
Tuple>::type>::create(std::get<Is>(t))))...};
}
} // namespace detail
+#endif // DOXYGEN_SHOULD_SKIP_THIS
template <class... Types>
Variant<std::tuple<Types...>>
@@ -1524,7 +1587,7 @@ Variant<std::tuple<Types...>>::create(const std::tuple<Types...>& data)
{
// create a vector containing all tuple values as variants
std::vector<Glib::VariantBase> variants;
- detail::expand_tuple(variants, data, std::index_sequence_for<Types...>{});
+ detail::expand_tuple(variants, data, detail::index_sequence_for<Types...>{});
using var_ptr = GVariant*;
var_ptr* const var_array = new var_ptr[sizeof... (Types)];
@@ -1556,6 +1619,7 @@ Variant<T> Variant<std::tuple<Types...>>::get_child_variant(gsize index) const
return entry;
}
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace detail
{
// swallows any argument
@@ -1567,13 +1631,14 @@ constexpr int any_arg(T&& arg)
}
template <class Tuple, std::size_t... Is>
-void assign_tuple(std::vector<VariantBase> &variants, Tuple & t, std::index_sequence<Is...>)
+void assign_tuple(std::vector<VariantBase> &variants, Tuple & t, detail::index_sequence<Is...>)
{
int i = 0;
using swallow = int[]; // ensures left to right order
(void)swallow {(any_arg(std::get<Is>(t) = VariantBase::cast_dynamic<Variant<typename
std::tuple_element<Is, Tuple>::type > >(variants[i++]).get()))...};
}
} // namespace detail
+#endif // DOXYGEN_SHOULD_SKIP_THIS
template <class... Types>
std::tuple<Types...> Variant<std::tuple<Types...>>::get() const
@@ -1589,7 +1654,7 @@ std::tuple<Types...> Variant<std::tuple<Types...>>::get() const
return i++;
};
swallow{(expander(get_child_variant<Types>(i)))...};
- detail::assign_tuple(variants, data, std::index_sequence_for<Types...>{});
+ detail::assign_tuple(variants, data, detail::index_sequence_for<Types...>{});
return data;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]