#ifndef _INIT_ITERATOR_GUARD #define _INIT_ITERATOR_GUARD #include #include #include #include #include #include #include #include #include #include "boost/mpl/if.hpp" namespace detail { template struct compile_time_init_iterator_data { ValueType value; compile_time_init_iterator_data* next; compile_time_init_iterator_data* prev; bool at_end; unsigned index; }; template struct empty_sequence_ct_iterator_data { static compile_time_init_iterator_data data; typedef empty_sequence_ct_iterator_data sequence_type; }; template compile_time_init_iterator_data empty_sequence_ct_iterator_data::data = { 0, /* value - dummy */ 0, /* next */ 0, /* prev */ true, /* at end */ 0, /* index */ }; template struct begin_sequence_ct_iterator_data { static compile_time_init_iterator_data data; typedef begin_sequence_ct_iterator_data sequence_type; }; template struct end_sequence_ct_iterator_data { static compile_time_init_iterator_data data; typedef end_sequence_ct_iterator_data sequence_type; }; template struct middle_sequence_ct_iterator_data { static compile_time_init_iterator_data data; typedef middle_sequence_ct_iterator_data sequence_type; }; template compile_time_init_iterator_data begin_sequence_ct_iterator_data::data = { boost::mpl::at >::type::value, /* value */ &sequence_ct_iterator_data<1, Sequence, ValueType>::sequence_type::data, /* next */ 0, /* prev */ false, /* at end */ 0, /* index */ }; template compile_time_init_iterator_data end_sequence_ct_iterator_data::data = { 0, /* value - dummy */ 0, /* next */ &sequence_ct_iterator_data::value - 1, Sequence, ValueType>::sequence_type::data, /* prev */ true, /* at end */ boost::mpl::size::value, /* index */ }; template compile_time_init_iterator_data middle_sequence_ct_iterator_data::data = { boost::mpl::at >::type::value, /* value */ &sequence_ct_iterator_data::sequence_type::data, /* next */ &sequence_ct_iterator_data::sequence_type::data, /* next */ false, /* at end */ Index, /* index */ }; template struct not_empty_sequence_ct_iterator_data { enum { sequence_size = boost::mpl::size::type::value }; typedef boost::mpl::if_c< Index == 0, begin_sequence_ct_iterator_data, boost::mpl::if_c< Index == sequence_size, end_sequence_ct_iterator_data, middle_sequence_ct_iterator_data >::type >::type::sequence_type sequence_type; }; template struct sequence_ct_iterator_data { enum { sequence_empty = boost::mpl::empty::type::value }; typedef boost::mpl::if_c< sequence_empty, empty_sequence_ct_iterator_data, not_empty_sequence_ct_iterator_data >::type::sequence_type sequence_type; }; template struct sequence_type { enum { sequence_empty = boost::mpl::empty::type::value }; typedef boost::mpl::if_c< sequence_empty, int, boost::mpl::at >::value_type >::type type; }; template class init_iterator_base { public: init_iterator_base() { } init_iterator_base(std::vector const& a_rhs) : values(new std::vector(a_rhs)) , current(values->begin()) { } bool operator==(const init_iterator_base& a_rhs) const { const bool am_at_end(at_end()); const bool rhs_at_end(a_rhs.at_end()); if (am_at_end || rhs_at_end) return am_at_end && rhs_at_end; return current == a_rhs.current; } bool at_end() const { return values.get() == 0 || current == values->end(); } void operator++() { ++current; } const T& operator*() const { return *current; } private: boost::shared_ptr > values; std::vector::const_iterator current; }; template class ct_init_iterator_base { public: ct_init_iterator_base() : sequence(0) {} template ct_init_iterator_base(Sequence*) : sequence(&sequence_ct_iterator_data<0, Sequence, T>::sequence_type::data) { } ct_init_iterator_base(const ct_init_iterator_base& a_rhs) : sequence(a_rhs.sequence) { } bool operator==(const ct_init_iterator_base& a_rhs) const { const bool am_at_end(at_end()); const bool rhs_at_end(a_rhs.at_end()); if (am_at_end || rhs_at_end) return am_at_end && rhs_at_end; return sequence->index == a_rhs.sequence->index; } bool at_end() const { return sequence == 0 || sequence->at_end; } void operator++() { sequence = sequence->next; } void operator--() { sequence = sequence->prev; } const T& operator*() const { return sequence->value; } private: compile_time_init_iterator_data* sequence; }; template struct init_iterator_generator { typedef boost::iterator_adaptor< init_iterator_base, boost::default_iterator_policies, const T, const T&, const T*, std::forward_iterator_tag, ptrdiff_t> type; }; template struct ct_init_iterator_generator { typedef SequenceType value_type; typedef ct_init_iterator_base base_type; typedef boost::iterator_adaptor< base_type, boost::default_iterator_policies, const value_type, const value_type&, const value_type*, std::bidirectional_iterator_tag, ptrdiff_t> iter_type; }; char is_pair_helper(...); template double is_pair_helper(const std::pair&); template struct is_pair { static P makeP(); enum { value = sizeof(double) == sizeof(is_pair_helper(makeP())) }; }; template class initializer { public: typedef init_iterator_generator::type iterator; initializer(boost::call_traits::param_type a_param) { values.push_back(a_param); } iterator operator()() const { return iterator(init_iterator_base(values)); } initializer& operator()(boost::call_traits::param_type a_param) { values.push_back(a_param); return *this; } private: std::vector values; }; template class pair_initializer { public: typedef init_iterator_generator::type iterator; pair_initializer(boost::call_traits::param_type a_param) { values.push_back(a_param); } pair_initializer( boost::call_traits::param_type a_first, boost::call_traits::param_type a_second) { values.push_back(T(a_first, a_second)); } iterator operator()() const { return iterator(init_iterator_base(values)); } pair_initializer& operator()(boost::call_traits::param_type a_param) { values.push_back(a_param); return *this; } pair_initializer& operator()( boost::call_traits::param_type a_first, boost::call_traits::param_type a_second) { values.push_back(T(a_first, a_second)); return *this; } private: std::vector values; }; template struct make_init_iterator_return { typedef boost::mpl::if_c::value, detail::pair_initializer, detail::initializer >::type type; }; } template detail::init_iterator_generator::type make_init_iterator() { return detail::init_iterator_generator::type( detail::init_iterator_base()); } template struct ct_init_iterator { typedef detail::ct_init_iterator_generator::iter_type iter_type; typedef detail::ct_init_iterator_generator generator_type; static iter_type type() { return iter_type(generator_type::base_type((Sequence*)0)); } }; template detail::make_init_iterator_return::type make_init_iterator( boost::call_traits::param_type a_param) { return detail::make_init_iterator_return::type(a_param); } template detail::pair_initializer make_init_iterator( boost::call_traits::param_type a_first, boost::call_traits::param_type a_second) { return detail::pair_initializer(a_first, a_second); } #endif