diff options
| author | Dennis Brentjes <d.brentjes@gmail.com> | 2014-05-15 14:52:31 +0200 |
|---|---|---|
| committer | Dennis Brentjes <d.brentjes@gmail.com> | 2014-05-15 14:52:31 +0200 |
| commit | 2f6c50d2764138583dcf89d86b13440a23f217cf (patch) | |
| tree | 08cc78ff875c1501375f7a28401da3b3fd327d82 /fusion_static_dispatch.hpp | |
| parent | 6a1e6120c4efc46f1d192b0e5fabc06b780113cc (diff) | |
| download | generic-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.hpp | 79 |
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](); |
