/** @file reversible_pmap.hpp @brief wrapper for a reversible property map */ #ifndef REVERSIBLE_PMAP_HPP #define REVERSIBLE_PMAP_HPP #include //#include #include #include namespace boost { template struct reversible_property_map { typedef PA Base; typedef property_traits Traits; // take definitions from base property map typedef typename Traits::key_type key_type; typedef typename Traits::value_type value_type; typedef typename Traits::reference reference; typedef typename Traits::category category; reversible_property_map(PA pmap, action_queue& aq) : m_pmap(pmap), m_aq(aq) {} reference operator[](const key_type k) const { return m_pmap[k]; } void undo_put(const key_type k, const value_type& val) { put(m_pmap, k, val); } // private: PA m_pmap; action_queue& m_aq; }; /* temporary objects are too expensive to generate namespace detail { // this helper object should actually not be necessary! template struct undo_put { typedef PA Property; typedef typename boost::property_traits Traits; typedef typename Traits::key_type key_type; typedef typename Traits::value_type value_type; undo_put(Property p, const key_type k, const value_type& val) : _p(p), _k(k), _v(val) {} void operator()() { put(_p, _k, _v); } private: Property _p; const key_type _k; const value_type _v; }; } */ template void put(reversible_property_map& rpa, const typename reversible_property_map::key_type k, const typename reversible_property_map::value_type& v) { // save old value into undo queue typename reversible_property_map::value_type oval = get(rpa.m_pmap, k); // using this lambda expression works, but produces segfaults if // used with optimizations of gcc :( //typedef detail::undo_put undo_functor; //rpa.m_aq.register_action(undo_functor(rpa.m_pmap, k, oval)); //typedef boost::function action_t; rpa.m_aq.register_action( bind(&reversible_property_map::undo_put, boost::ref(rpa), k, oval) ); // ok, now acutally do the put put(rpa.m_pmap, k, v); } template inline const typename reversible_property_map::reference get(reversible_property_map& rpa, const typename reversible_property_map::key_type k) { return static_cast&>(rpa)[k]; } // convenience function template reversible_property_map make_reversible_pmap(PA p, action_queue& aq) { return reversible_property_map(p, aq); } } #endif