tree.hpp 3.0 KB

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