c++ - Traversing boost::month_iterators using ranges -


i'm trying come idomatic way of writing this

boost::gregorian::month_iterator start(boost::gregorian::date(1901,1,1),1); boost::gregorian::date end(2000,12,31); int = 0; while(start <= end) {     boost::gregorian::gregorian_calendar::day_of_week_type x = (*start).day_of_week(); if(x==0)       ++i; } 

this fine, wondered if there way of writing like

boost::gregorian::month_iterator start(boost::gregorian::date(1901,1,1),1); boost::gregorian::month_iterator end(boost::gregorian::date(2000,12,31));  const int = std::count_if(start,end,[](boost::gregorian::month_iterator& start) {     boost::gregorian::gregorian_calendar::day_of_week_type x = (*start).day_of_week();     return (x==0); }); 

same result, think it's prettier code, it's more functional approach (which like) , intention of i'm trying achieve clearer. have feeling have use any_range<> i'm not sure how in case month_iterator doesn't seem have normal semantics of forward iterators

there no simple way this. firstly should specialize std::iterator_traits example this

namespace std {  template<> struct iterator_traits<boost::gregorian::month_iterator> {    typedef ptrdiff_t difference_type;    typedef boost::gregorian::month_iterator value_type;    typedef boost::gregorian::month_iterator& reference;    typedef boost::gregorian::month_iterator* pointer; };  } 

secondly, cannot use boost::range since there no operator == 2 iterators , there no operator * const. so, should write own class, derived boost::iterator_adaptor, however, think, iterator not created such usage.

i'm writing small example, not effective, works , there no excessively complexity.

#include <boost/range.hpp> #include <boost/range/any_range.hpp> #include <boost/date_time/gregorian/gregorian.hpp> #include <boost/shared_ptr.hpp>  #include <vector>  namespace std {  template<> struct iterator_traits<boost::gregorian::month_iterator> {    typedef ptrdiff_t difference_type;    typedef boost::gregorian::month_iterator value_type;    typedef boost::gregorian::month_iterator& reference;    typedef boost::gregorian::month_iterator* pointer; };  }  class month_iterator : public boost::iterator_adaptor <    month_iterator,    boost::gregorian::month_iterator*,    boost::gregorian::month_iterator::value_type,    boost::bidirectional_traversal_tag,    boost::gregorian::month_iterator::value_type& > {    friend class boost::iterator_core_access; public:    month_iterator() : m_it(boost::gregorian::date(boost::gregorian::not_a_date_time)) {}    explicit month_iterator(const boost::gregorian::month_iterator& pos) :       m_it(pos)    {       receive_value();    }    reference dereference() const    {       return *value;    }    bool equal(const month_iterator& rhs) const    {       return *value >= *rhs.value;    }    void increment()    {       ++m_it;       *this = month_iterator(m_it);    } private:    void receive_value()    {       value.reset(new value_type(*m_it));    }    boost::gregorian::month_iterator m_it;    boost::shared_ptr<value_type> value; };  int main() {    boost::gregorian::month_iterator start(boost::gregorian::date(1901,1,1),1);    boost::gregorian::month_iterator end(boost::gregorian::date(2000,12,31));     month_iterator p(start), e(end);    const int result = std::count_if(p, e, [](const month_iterator::value_type& v)    {       return v.day_of_week() == 0;    });    std::cout << result << std::endl; } 

Comments

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -