|
Sierra Toolkit
Version of the Day
|
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_classic { 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