/*============================================================================= | |
Copyright (c) 2006 Eric Niebler | |
Use, modification and distribution is subject to the Boost Software | |
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
http://www.boost.org/LICENSE_1_0.txt) | |
==============================================================================*/ | |
#ifndef FUSION_BINARY_TREE_EAN_05032006_1027 | |
#define FUSION_BINARY_TREE_EAN_05032006_1027 | |
#include <boost/mpl/if.hpp> | |
#include <boost/type_traits/is_const.hpp> | |
#include <boost/type_traits/add_const.hpp> | |
#include <boost/type_traits/add_reference.hpp> | |
#include <boost/fusion/support/is_sequence.hpp> | |
#include <boost/fusion/sequence/intrinsic/at.hpp> | |
#include <boost/fusion/view/single_view.hpp> | |
#include <boost/fusion/container/list/cons.hpp> // for nil | |
#include <boost/fusion/container/vector/vector10.hpp> | |
#include <boost/fusion/support/sequence_base.hpp> | |
#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp> | |
#include <boost/fusion/support/ext_/is_segmented.hpp> | |
#include <boost/fusion/view/ext_/segmented_iterator.hpp> | |
namespace boost { namespace fusion | |
{ | |
struct tree_tag; | |
namespace detail | |
{ | |
template<typename T, bool IsConst> | |
struct reference : add_reference<T> {}; | |
template<typename T> | |
struct reference<T, true> : reference<typename add_const<T>::type, false> {}; | |
template<typename T> | |
struct reference<T &, true> : reference<T, false> {}; | |
} | |
template<typename Data, typename Left = nil, typename Right = nil> | |
struct tree | |
: sequence_base<tree<Data, Left, Right> > | |
{ | |
typedef Data data_type; | |
typedef Left left_type; | |
typedef Right right_type; | |
typedef tree_tag fusion_tag; | |
typedef forward_traversal_tag category; | |
typedef mpl::false_ is_view; | |
typedef typename mpl::if_< | |
traits::is_sequence<Data> | |
, Data | |
, single_view<Data> | |
>::type data_view; | |
explicit tree( | |
typename fusion::detail::call_param<Data>::type data_ | |
, typename fusion::detail::call_param<Left>::type left_ = Left() | |
, typename fusion::detail::call_param<Right>::type right_ = Right() | |
) | |
: segments(left_, data_view(data_), right_) | |
{} | |
typedef vector3<Left, data_view, Right> segments_type; | |
segments_type segments; | |
}; | |
template<typename Data> | |
tree<Data> make_tree(Data const &data) | |
{ | |
return tree<Data>(data); | |
} | |
template<typename Data, typename Left, typename Right> | |
tree<Data, Left, Right> make_tree(Data const &data, Left const &left, Right const &right) | |
{ | |
return tree<Data, Left, Right>(data, left, right); | |
} | |
namespace extension | |
{ | |
template<> | |
struct is_segmented_impl<tree_tag> | |
{ | |
template<typename Sequence> | |
struct apply : mpl::true_ {}; | |
}; | |
template<> | |
struct segments_impl<tree_tag> | |
{ | |
template<typename Sequence> | |
struct apply | |
{ | |
typedef typename mpl::if_< | |
is_const<Sequence> | |
, typename Sequence::segments_type const & | |
, typename Sequence::segments_type & | |
>::type type; | |
static type call(Sequence &seq) | |
{ | |
return seq.segments; | |
} | |
}; | |
}; | |
template<> | |
struct begin_impl<tree_tag> | |
{ | |
template<typename Sequence> | |
struct apply | |
: segmented_begin<Sequence> | |
{}; | |
}; | |
template<> | |
struct end_impl<tree_tag> | |
{ | |
template<typename Sequence> | |
struct apply | |
: segmented_end<Sequence> | |
{}; | |
}; | |
} | |
}} | |
#endif |