summaryrefslogtreecommitdiff
path: root/fusion_static_dispatch.hpp
diff options
context:
space:
mode:
authorDennis Brentjes <d.brentjes@gmail.com>2014-05-15 14:52:31 +0200
committerDennis Brentjes <d.brentjes@gmail.com>2014-05-15 14:52:31 +0200
commit2f6c50d2764138583dcf89d86b13440a23f217cf (patch)
tree08cc78ff875c1501375f7a28401da3b3fd327d82 /fusion_static_dispatch.hpp
parent6a1e6120c4efc46f1d192b0e5fabc06b780113cc (diff)
downloadgeneric-gui-2f6c50d2764138583dcf89d86b13440a23f217cf.tar.gz
generic-gui-2f6c50d2764138583dcf89d86b13440a23f217cf.tar.bz2
generic-gui-2f6c50d2764138583dcf89d86b13440a23f217cf.zip
3 major changes.
Renamed fusion_model to FusionModel to follow the naming convention. Added observers so models can be shared over views and update properly. Constness in datastructure now makes the data uneditable.
Diffstat (limited to 'fusion_static_dispatch.hpp')
-rw-r--r--fusion_static_dispatch.hpp79
1 files changed, 46 insertions, 33 deletions
diff --git a/fusion_static_dispatch.hpp b/fusion_static_dispatch.hpp
index ce81c90..9240cc2 100644
--- a/fusion_static_dispatch.hpp
+++ b/fusion_static_dispatch.hpp
@@ -6,8 +6,36 @@
#include <boost/any.hpp>
#include <functional>
+#include <iostream>
+
+template <typename T, int... Indices>
+bool is_const_impl(int index, indices<Indices...>)
+{
+ typedef std::function<bool()> element_type;
+ static element_type table[] = {
+ [] {
+ typedef friendly_fusion::result_of::begin<T> begin;
+ typedef friendly_fusion::result_of::advance_c<typename begin::type, Indices> adv_it;
+ typedef friendly_fusion::result_of::deref<typename adv_it::type> deref;
+ typedef std::remove_reference<typename deref::type> unreferenced_type;
+
+ return std::is_const<typename unreferenced_type::type>::value;
+ }
+ ...
+ };
+
+ return table[index]();
+}
+
+template <typename T>
+bool is_const(int index)
+{
+ typedef typename friendly_fusion::result_of::size<T>::type seq_size;
+ typedef typename build_indices<seq_size::value>::type indices_type;
+
+ return is_const_impl<T>(index, indices_type{});
+}
-#if defined( __GNUC__ ) && !defined( __clang__ )
template<int index, typename T>
std::function<boost::any(T)> make_at_c_lambda(T seq)
{
@@ -15,7 +43,6 @@ std::function<boost::any(T)> make_at_c_lambda(T seq)
return boost::any(friendly_fusion::deref(friendly_fusion::advance_c<index>(friendly_fusion::begin(seq))));
};
}
-#endif //defined( __GNUC__ ) && !defined( __clang__ )
template<typename T, int... Indices>
boost::any get_nth_impl(T seq, int index, indices<Indices...>)
@@ -23,14 +50,8 @@ boost::any get_nth_impl(T seq, int index, indices<Indices...>)
typedef std::function<boost::any(T)> element_type;
static element_type table[] =
{
-#if defined( __GNUC__ ) && !defined( __clang__ )
- //Workaround for gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226
make_at_c_lambda<Indices>(seq)
...
-#else
- [](T seq){return boost::any(friendly_fusion::deref(friendly_fusion::advance_c<Indices>(friendly_fusion::begin(seq))));}
- ...
-#endif //defined( __GNUC__ ) && !defined( __clang__ )
};
return table[index](seq);
@@ -54,7 +75,20 @@ boost::any get_nth(T x, int index)
return get_nth_functor<T>()(x, index);
}
-#if defined( __GNUC__ ) && !defined( __clang__ )
+template <bool b, typename T, typename V>
+typename std::enable_if<b, void>::type assign(T&, V)
+{
+ //this function will never be called, but has to be defined.
+ //We need to generate a assign statement for all members at compile time even when they are const.
+ return;
+}
+
+template <bool b, typename T, typename V>
+typename std::enable_if<!b, void>::type assign(T& lh, V rh)
+{
+ lh = rh;
+}
+
template<int index, typename T>
std::function<void(T&, boost::any const&)> make_set_nth_lambda()
{
@@ -63,11 +97,11 @@ std::function<void(T&, boost::any const&)> make_set_nth_lambda()
typedef friendly_fusion::result_of::advance_c<typename begin::type, index> adv_it;
typedef friendly_fusion::result_of::deref<typename adv_it::type> deref;
typedef typename std::decay<typename deref::type>::type value_type;
+ typedef typename std::remove_reference<typename deref::type>::type unreferenced_type;
- friendly_fusion::deref(friendly_fusion::advance_c<index>(friendly_fusion::begin(seq))) = boost::any_cast<value_type>(value);
+ assign<std::is_const<unreferenced_type>::value>(friendly_fusion::deref(friendly_fusion::advance_c<index>(friendly_fusion::begin(seq))), boost::any_cast<value_type>(value));
};
}
-#endif //defined( __GNUC__ ) && !defined( __clang__ )
template <typename T, int... Indices>
void set_nth_impl(T& seq, int index, boost::any const& value, indices<Indices...>)
@@ -75,21 +109,8 @@ void set_nth_impl(T& seq, int index, boost::any const& value, indices<Indices...
typedef std::function<void(T&, boost::any const&)> element_type;
static element_type table[] =
{
- #if defined( __GNUC__ ) && !defined( __clang__ )
- make_set_nth_lambda<Indices, T>()
- ...
- #else
- [](T& seq, boost::any const& value)
- {
- typedef friendly_fusion::result_of::begin<T> begin;
- typedef friendly_fusion::result_of::advance_c<typename begin::type, Indices> adv_it;
- typedef friendly_fusion::result_of::deref<typename adv_it::type> deref;
- typedef typename std::decay<typename deref::type>::type value_type;
-
- friendly_fusion::deref(friendly_fusion::advance_c<Indices>(friendly_fusion::begin(seq))) = boost::any_cast<value_type>(value);
- }
+ make_set_nth_lambda<Indices, T>()
...
- #endif //defined( __GNUC__ ) && !defined( __clang__ )
};
table[index](seq, value);
@@ -113,7 +134,6 @@ void set_nth(T& x, int index, boost::any const& value)
set_nth_functor<T>()(x, index, value);
}
-#if defined( __GNUC__ ) && !defined( __clang__ )
template<int index, typename T>
std::function<std::string()> make_struct_member_name_lambda()
{
@@ -121,8 +141,6 @@ std::function<std::string()> make_struct_member_name_lambda()
return std::string(friendly_fusion::extension::struct_member_name<T, index>::call());
};
}
-#endif //defined( __GNUC__ ) && !defined( __clang__ )
-
template<typename T>
struct get_nth_name_impl {
@@ -133,14 +151,9 @@ struct get_nth_name_impl {
{
typedef std::function<std::string()> element_type;
static element_type table[] = {
- #if defined( __GNUC__ ) && !defined( __clang__ )
//Workaround for gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226
make_struct_member_name_lambda<Indices, T>()
...
- #else
- []{return std::string(friendly_fusion::extension::struct_member_name<T, Indices>::call());}
- ...
- #endif //defined( __GNUC__ ) && !defined( __clang__ )
};
return table[index]();