1 /*============================================================================= 2 Copyright (c) 2006 Eric Niebler 3 4 Use, modification and distribution is subject to the Boost Software 5 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 6 http://www.boost.org/LICENSE_1_0.txt) 7 ==============================================================================*/ 8 #ifndef FUSION_BINARY_TREE_EAN_05032006_1027 9 #define FUSION_BINARY_TREE_EAN_05032006_1027 10 11 #include <boost/mpl/if.hpp> 12 #include <boost/type_traits/is_const.hpp> 13 #include <boost/type_traits/add_const.hpp> 14 #include <boost/type_traits/add_reference.hpp> 15 #include <boost/fusion/support/is_sequence.hpp> 16 #include <boost/fusion/sequence/intrinsic/at.hpp> 17 #include <boost/fusion/view/single_view.hpp> 18 #include <boost/fusion/container/list/cons.hpp> // for nil 19 #include <boost/fusion/container/vector/vector10.hpp> 20 #include <boost/fusion/support/sequence_base.hpp> 21 #include <boost/fusion/support/category_of.hpp> 22 #include <boost/fusion/support/is_segmented.hpp> 23 #include <boost/fusion/sequence/intrinsic/segments.hpp> 24 25 namespace boost { namespace fusion 26 { 27 struct tree_tag; 28 29 template <typename Data, typename Left = nil, typename Right = nil> 30 struct tree 31 : sequence_base<tree<Data, Left, Right> > 32 { 33 typedef Data data_type; 34 typedef Left left_type; 35 typedef Right right_type; 36 typedef tree_tag fusion_tag; 37 typedef forward_traversal_tag category; 38 typedef mpl::false_ is_view; 39 40 typedef typename mpl::if_< 41 traits::is_sequence<Data> 42 , Data 43 , single_view<Data> 44 >::type data_view; 45 treeboost::fusion::tree46 explicit tree( 47 typename fusion::detail::call_param<Data>::type data_ 48 , typename fusion::detail::call_param<Left>::type left_ = Left() 49 , typename fusion::detail::call_param<Right>::type right_ = Right() 50 ) 51 : segments(left_, data_view(data_), right_) 52 {} 53 54 typedef vector3<Left, data_view, Right> segments_type; 55 segments_type segments; 56 }; 57 58 template <typename Data> make_tree(Data const & data)59 tree<Data> make_tree(Data const &data) 60 { 61 return tree<Data>(data); 62 } 63 64 template <typename Data, typename Left, typename Right> make_tree(Data const & data,Left const & left,Right const & right)65 tree<Data, Left, Right> make_tree(Data const &data, Left const &left, Right const &right) 66 { 67 return tree<Data, Left, Right>(data, left, right); 68 } 69 70 namespace extension 71 { 72 template <> 73 struct is_segmented_impl<tree_tag> 74 { 75 template <typename Sequence> 76 struct apply : mpl::true_ {}; 77 }; 78 79 template <> 80 struct segments_impl<tree_tag> 81 { 82 template <typename Sequence> 83 struct apply 84 { 85 typedef typename mpl::if_< 86 is_const<Sequence> 87 , typename Sequence::segments_type const & 88 , typename Sequence::segments_type & 89 >::type type; 90 callboost::fusion::extension::segments_impl::apply91 static type call(Sequence &seq) 92 { 93 return seq.segments; 94 } 95 }; 96 }; 97 } 98 }} 99 100 #endif 101