Created
February 23, 2014 01:10
-
-
Save amedama41/9165134 to your computer and use it in GitHub Desktop.
BGL property iterator for Boost.Fusion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef CANARD_PROPERTY_SEQUENCE_BEGIN_IMPL_HPP | |
#define CANARD_PROPERTY_SEQUENCE_BEGIN_IMPL_HPP | |
#include <boost/fusion/sequence/intrinsic.hpp> | |
#include "property_sequence.hpp" | |
#include "property_iterator.hpp" | |
namespace boost { | |
namespace fusion { | |
namespace extension { | |
template <> | |
struct begin_impl<canard::property_tag> | |
{ | |
template <class Property> | |
struct apply | |
{ | |
using type = canard::property_iterator<Property>; | |
static type call(Property& p) | |
{ | |
return type{p}; | |
} | |
}; | |
}; | |
} | |
} | |
} | |
#endif | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef CANARD_PROPERTY_SEQUENCE_END_IMPL_HPP | |
#define CANARD_PROPERTY_SEQUENCE_END_IMPL_HPP | |
#include <boost/fusion/sequence/intrinsic.hpp> | |
#include "property_sequence.hpp" | |
#include "property_iterator.hpp" | |
namespace boost { | |
namespace fusion { | |
namespace extension { | |
template <> | |
struct end_impl<canard::property_tag> | |
{ | |
template <class Property> | |
struct apply | |
{ | |
using type = canard::property_iterator<boost::no_property>; | |
static type call(Property& p) | |
{ | |
return type{}; | |
} | |
}; | |
}; | |
} | |
} | |
} | |
#endif | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef CANARD_PROPERTY_SEQUENCE_ITERATOR_HPP | |
#define CANARD_PROPERTY_SEQUENCE_ITERATOR_HPP | |
#include <cstddef> | |
#include <boost/graph/properties.hpp> | |
#include <boost/fusion/iterator/iterator_facade.hpp> | |
namespace canard { | |
template <class T> | |
struct property_iterator; | |
template <class Tag, class T, class Base> | |
struct property_iterator<boost::property<Tag, T, Base>> | |
: boost::fusion::iterator_facade< | |
property_iterator<boost::property<Tag, T, Base>> | |
, boost::fusion::associative_tag | |
> | |
{ | |
using Property = boost::property<Tag, T, Base>; | |
property_iterator(Property& property) | |
: property_{property} | |
{ | |
} | |
template <class Iterator> | |
struct value_of | |
{ | |
using type = typename Iterator::Property; | |
}; | |
template <class Iterator> | |
struct deref | |
{ | |
using type = decltype((std::declval<Iterator>().property_)); | |
static type call(Iterator const& it) | |
{ | |
return it.property_; | |
} | |
}; | |
template <class Iterator> | |
struct next | |
{ | |
template <class U> | |
struct next_type | |
{ | |
using type = boost::no_property; | |
}; | |
template <class Tag2, class T2, class Base2> | |
struct next_type<boost::property<Tag2, T2, Base2>> | |
{ | |
using type = boost::property<Tag2, T2, Base2>; | |
}; | |
using type = property_iterator<typename next_type<Base>::type>; | |
static type call(Iterator const& it) | |
{ | |
return type{it.property_.m_base}; | |
} | |
}; | |
template <class Iterator, std::size_t N> | |
struct advance | |
{ | |
using type = typename advance<next<Iterator>, N - 1>::type; | |
static type call(Iterator const& it) | |
{ | |
return advance<typename next<Iterator>::type, N - 1>::call(next<Iterator>::call(it)); | |
} | |
}; | |
template <class Iterator> | |
struct advance<Iterator, 0> | |
{ | |
using type = Iterator; | |
static type call(Iterator const& it) | |
{ | |
return it; | |
} | |
}; | |
template <class Iterator> | |
struct key_of | |
{ | |
using type = typename Iterator::Property::tag_type; | |
}; | |
template <class Iterator> | |
struct value_of_data | |
{ | |
using type = typename Iterator::Property::value_type; | |
}; | |
template <class Iterator> | |
struct deref_data | |
{ | |
using type = decltype((std::declval<typename Iterator::Property>().m_value)); | |
static type call(Iterator const& it) | |
{ | |
return it.property_.m_value; | |
} | |
}; | |
Property& property_; | |
}; | |
template <> | |
struct property_iterator<boost::no_property> | |
: boost::fusion::iterator_facade< | |
property_iterator<boost::no_property> | |
, boost::fusion::associative_tag | |
> | |
{ | |
property_iterator() | |
{ | |
} | |
template <class T> | |
explicit property_iterator(T const&) | |
{ | |
} | |
}; | |
}; | |
#endif | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef CANARD_PROPERTY_SEQUENCE_SUPPORT_HPP | |
#define CANARD_PROPERTY_SEQUENCE_SUPPORT_HPP | |
#include <boost/fusion/support.hpp> | |
#include <boost/mpl/bool.hpp> | |
#include <boost/graph/properties.hpp> | |
namespace canard { | |
struct property_tag; | |
} | |
namespace boost { | |
namespace fusion { | |
namespace extension { | |
template <> | |
struct is_sequence_impl<canard::property_tag> | |
{ | |
template <class Property> | |
struct apply : boost::mpl::true_ | |
{ | |
}; | |
}; | |
template <> | |
struct category_of_impl<canard::property_tag> | |
{ | |
template <class Property> | |
struct apply | |
{ | |
struct type | |
: fusion::forward_traversal_tag | |
, fusion::associative_tag | |
{ | |
}; | |
}; | |
}; | |
} | |
namespace traits { | |
template <class Tag, class T, class Base> | |
struct tag_of<boost::property<Tag, T, Base>> | |
{ | |
using type = canard::property_tag; | |
}; | |
template <class Tag, class T, class Base> | |
struct tag_of<boost::property<Tag, T, Base> const> | |
{ | |
using type = canard::property_tag; | |
}; | |
} | |
} | |
} | |
#endif | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment