31 #include <ableton/build_system/Warnings.hpp>
33 #include <boost/operators.hpp>
34 #include <boost/fusion/include/adapt_struct.hpp>
35 #include <boost/fusion/include/fold.hpp>
36 #include <boost/fusion/include/comparison.hpp>
37 #include <boost/fusion/include/out.hpp>
50 std::size_t hash_value(
const T& v)
52 return std::hash<T>{}(v);
57 void hash_combine(std::size_t& seed,
const T& v)
59 seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
62 struct hash_combine_fn
65 std::size_t operator()(std::size_t seed,
const T& v)
const
67 hash_combine(seed, v);
72 struct first_equal_to_second
75 bool operator()(
const T& x)
const
77 using namespace boost::fusion;
78 return at_c<0>(x) == at_c<1>(x);
89 : boost::equality_comparable<structure<T> >
90 , boost::less_than_comparable<structure<T> >
99 std::size_t hash()
const
110 using namespace boost::fusion;
111 auto hash = fold(
self(), 0, detail::hash_combine_fn{});
122 const T&
self()
const {
return *
static_cast<const T*
>(
this); }
123 T&
self() {
return *
static_cast<const T*
>(
this); }
126 mutable std::size_t mHash = 0;
129 template <
typename T>
134 if (a.hash() != b.hash())
136 return boost::fusion::equal_to(a.self(), b.self());
139 template <
typename T>
140 bool operator<(const structure<T>& a,
const structure<T>& b)
142 return boost::fusion::less(a.self(), b.self());
145 template <
typename T>
146 auto operator<<(std::ostream& os,
const T& x)
147 -> estd::enable_if_t<std::is_convertible<T&, structure<T>&>::value,
150 os <<
typeid(x).name();
159 template <
typename T>
164 template <
typename T>
175 template <
typename T>
176 struct hash<
atria::funken::structure<T> >
186 #define ABL_FUNKEN_STRUCT(structure_full_name, structure_members) \
187 BOOST_FUSION_ADAPT_STRUCT(structure_full_name, structure_members) \
190 struct hash<structure_full_name> \
191 : hash<atria::funken::structure<structure_full_name> > \
auto out(OutT &&object) -> estd::enable_if_t< (Out_value< OutT >()), detail::output_impl< detail::signal_type_t< OutT > > >
Creates an out from another out value.
typename std::enable_if< X, T >::type enable_if_t
Similar to C++14 std::enable_if_t.
auto modified(T &) -> estd::enable_if_t<!std::is_convertible< T &, structure< T > & >::value >
Call this on an structure value to indicate that is has indeed changed, invalidating its cached value...
C++ amazing templates and reusable implementations awesomeness.