Sierra Toolkit Version of the Day
nested_range.hpp
00001 #ifndef STK_UTIL_STK_UTIL_UTIL_NESTED_RANGE_HPP
00002 #define STK_UTIL_STK_UTIL_UTIL_NESTED_RANGE_HPP
00003 
00004 #include <stk_util/util/nested_iterator.hpp>
00005 
00006 #include <boost/range.hpp>
00007 #include <boost/iterator.hpp>
00008 #include <boost/optional.hpp>
00009 
00010 #include <boost/mpl/assert.hpp>
00011 #include <boost/type_traits.hpp>
00012 
00013 namespace stk {
00014 namespace util {
00015 
00016 namespace details {
00017 
00018 template<typename T>
00019 struct identity {
00020   typedef T result_type;
00021 
00022   result_type& operator()(result_type& r) const { return r; }
00023   const result_type& operator()(const result_type& r) const { return r; }
00024 };
00025 
00026 }
00027 
00030 template < typename OuterRange,
00031            typename InnerRange=typename boost::range_value<OuterRange>::type,
00032            typename OuterToInnerConverter=
00033              details::identity<
00034                typename boost::mpl::if_<
00035                  typename boost::is_same<InnerRange,
00036                                          typename boost::range_value<OuterRange>::type>,
00037                  InnerRange,
00038                  void
00039                >::type
00040              >
00041          >
00042 class nested_range;
00043 
00044 template < typename OuterRange, typename InnerRange, typename OuterToInnerConverter >
00045 class nested_range
00046 {
00047   public:
00048     typedef OuterRange outer_range;
00049     typedef InnerRange inner_range;
00050     BOOST_MPL_ASSERT((boost::has_range_iterator<outer_range>));
00051     BOOST_MPL_ASSERT((boost::has_range_iterator<inner_range>));
00052 
00053     typedef OuterToInnerConverter converter_type;
00054 
00055     typedef nested_iterator<outer_range,inner_range,converter_type> iterator;
00056     typedef nested_iterator<typename boost::add_const<outer_range>::type,inner_range,converter_type> const_iterator;
00057 
00058   nested_range() : m_outer(), m_converter() {}
00059 
00060   nested_range(outer_range& outer, converter_type converter=converter_type()) : m_outer(outer), m_converter(converter) {}
00061 
00062   iterator begin() { return iterator(*m_outer, *m_converter); }
00063   const_iterator begin() const { return const_iterator(*m_outer, *m_converter); }
00064 
00065   iterator end() { return iterator(); }
00066   const_iterator end() const { return const_iterator(); }
00067 
00068   private:
00069     boost::optional<outer_range&> m_outer;
00070     boost::optional<converter_type> m_converter;
00071 };
00072 
00073 //template < typename OuterRange>
00074 //class nested_range<OuterRange,typename boost::range_value<OuterRange>::type, void>
00075 //{
00076 //  public:
00077 //    typedef OuterRange outer_range;
00078 //    typedef InnerRange inner_range;
00079 //    BOOST_MPL_ASSERT((boost::has_range_iterator<inner_range>));
00080 //
00081 //    typedef nested_iterator<outer_range,inner_range> iterator;
00082 //    typedef nested_iterator<typename boost::add_const<outer_range>::type,inner_range> const_iterator;
00083 //
00084 //  nested_range() : m_outer() {}
00085 //
00086 //  nested_range(outer_range& outer) : m_outer(outer) {}
00087 //
00088 //  iterator begin() { return iterator(*m_outer); }
00089 //  const_iterator begin() const { return const_iterator(*m_outer); }
00090 //
00091 //  iterator end() { return iterator(); }
00092 //  const_iterator end() const { return const_iterator(); }
00093 //
00094 //  private:
00095 //    boost::optional<outer_range&> m_outer;
00096 //};
00097 
00098 
00099 } // util
00100 } // stk
00101 
00102 
00103 #endif //STK_UTIL_STK_UTIL_UTIL_NESTED_RANGE_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines