Project

General

Profile

Actions

Bug #2425

closed

Name doesn't conform to SinglePassRangeConcept

Added by Alex Afanasyev about 9 years ago. Updated almost 7 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Base
Target version:
Start date:
01/27/2015
Due date:
% Done:

100%

Estimated time:
1.50 h

Description

This is necessary, for example, to use boost::adaptors::reversed

Code snippet (test.cpp)

#include <ndn-cxx/name.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <iostream>

int main()
{
    ndn::Name test("/hello/world");
    for (const auto& i : test | boost::adaptors::reversed) {
        std::cout << i << std::endl;
    }
    return 0;
}

Compile

g++ test.cpp -std=c++11 `pkg-config --cflags --ldflags libndn-cxx`

Expected: compiles

Actual:

In file included from test.cpp:2:
In file included from /usr/local/include/boost/range/adaptor/reversed.hpp:14:
In file included from /usr/local/include/boost/range/iterator_range.hpp:13:
In file included from /usr/local/include/boost/range/iterator_range_core.hpp:38:
In file included from /usr/local/include/boost/range/functions.hpp:18:
/usr/local/include/boost/range/begin.hpp:47:16: error: cannot initialize return object of type 'typename range_iterator<Name>::type'
      (aka 'ndn::name::Component *') with an rvalue of type 'const_iterator' (aka 'const ndn::name::Component *')
        return c.begin();
               ^~~~~~~~~
/usr/local/include/boost/range/begin.hpp:102:12: note: in instantiation of function template specialization
      'boost::range_detail::range_begin<ndn::Name>' requested here
    return range_begin( r );
           ^
/usr/local/include/boost/range/concepts.hpp:287:34: note: in instantiation of function template specialization
      'boost::range_adl_barrier::begin<ndn::Name>' requested here
            iterator i1 = boost::begin(*m_range);
                                 ^
/usr/local/include/boost/concept/usage.hpp:16:43: note: in instantiation of member function
      'boost::SinglePassRangeConcept<ndn::Name>::~SinglePassRangeConcept' requested here
    ~usage_requirements() { ((Model*)0)->~Model(); }
                                          ^
/usr/local/include/boost/concept/detail/general.hpp:38:42: note: in instantiation of member function
      'boost::concepts::usage_requirements<boost::SinglePassRangeConcept<ndn::Name> >::~usage_requirements' requested here
    static void failed() { ((Model*)0)->~Model(); }
                                         ^
/usr/local/include/boost/range/concepts.hpp:282:9: note: in instantiation of member function 'boost::concepts::requirement<boost::concepts::failed
      ************boost::concepts::usage_requirements<boost::SinglePassRangeConcept<ndn::Name> >::************>::failed' requested here
        BOOST_CONCEPT_USAGE(SinglePassRangeConcept)
        ^
/usr/local/include/boost/concept/usage.hpp:29:7: note: expanded from macro 'BOOST_CONCEPT_USAGE'
      BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements<model>)); \
      ^
/usr/local/include/boost/concept/assert.hpp:43:5: note: expanded from macro 'BOOST_CONCEPT_ASSERT'
    BOOST_CONCEPT_ASSERT_FN(void(*)ModelInParens)
    ^
/usr/local/include/boost/concept/detail/general.hpp:78:51: note: expanded from macro 'BOOST_CONCEPT_ASSERT_FN'
    &::boost::concepts::requirement_<ModelFnPtr>::failed>    \
                                                  ^
test.cpp:8:31: note: in instantiation of function template specialization 'boost::range_detail::operator|<ndn::Name>' requested here
    for (const auto& i : test | boost::adaptors::reversed) {
                              ^
In file included from test.cpp:2:
In file included from /usr/local/include/boost/range/adaptor/reversed.hpp:14:
In file included from /usr/local/include/boost/range/iterator_range.hpp:13:
In file included from /usr/local/include/boost/range/iterator_range_core.hpp:38:
In file included from /usr/local/include/boost/range/functions.hpp:19:
/usr/local/include/boost/range/end.hpp:48:20: error: cannot initialize return object of type 'typename range_iterator<Name>::type'
      (aka 'ndn::name::Component *') with an rvalue of type 'const_iterator' (aka 'const ndn::name::Component *')
            return c.end();
                   ^~~~~~~
/usr/local/include/boost/range/end.hpp:96:12: note: in instantiation of function template specialization 'boost::range_detail::range_end<ndn::Name>'
      requested here
    return range_end( r );
           ^
/usr/local/include/boost/range/concepts.hpp:288:34: note: in instantiation of function template specialization
      'boost::range_adl_barrier::end<ndn::Name>' requested here
            iterator i2 = boost::end(*m_range);
                                 ^
/usr/local/include/boost/concept/usage.hpp:16:43: note: in instantiation of member function
      'boost::SinglePassRangeConcept<ndn::Name>::~SinglePassRangeConcept' requested here
    ~usage_requirements() { ((Model*)0)->~Model(); }
                                          ^
/usr/local/include/boost/concept/detail/general.hpp:38:42: note: in instantiation of member function
      'boost::concepts::usage_requirements<boost::SinglePassRangeConcept<ndn::Name> >::~usage_requirements' requested here
    static void failed() { ((Model*)0)->~Model(); }
                                         ^
/usr/local/include/boost/range/concepts.hpp:282:9: note: in instantiation of member function 'boost::concepts::requirement<boost::concepts::failed
      ************boost::concepts::usage_requirements<boost::SinglePassRangeConcept<ndn::Name> >::************>::failed' requested here
        BOOST_CONCEPT_USAGE(SinglePassRangeConcept)
        ^
/usr/local/include/boost/concept/usage.hpp:29:7: note: expanded from macro 'BOOST_CONCEPT_USAGE'
      BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements<model>)); \
      ^
/usr/local/include/boost/concept/assert.hpp:43:5: note: expanded from macro 'BOOST_CONCEPT_ASSERT'
    BOOST_CONCEPT_ASSERT_FN(void(*)ModelInParens)
    ^
/usr/local/include/boost/concept/detail/general.hpp:78:51: note: expanded from macro 'BOOST_CONCEPT_ASSERT_FN'
    &::boost::concepts::requirement_<ModelFnPtr>::failed>    \
                                                  ^
test.cpp:8:31: note: in instantiation of function template specialization 'boost::range_detail::operator|<ndn::Name>' requested here
    for (const auto& i : test | boost::adaptors::reversed) {
                              ^
2 errors generated.
Actions #1

Updated by Davide Pesavento about 9 years ago

For reference: http://www.boost.org/doc/libs/1_57_0/libs/range/doc/html/range/concepts/single_pass_range.html

Looks like a const-ness problems with iterators.

Actions #2

Updated by Junxiao Shi about 9 years ago

  • Category set to Base
  • Estimated time set to 1.50 h
Actions #3

Updated by Junxiao Shi almost 7 years ago

  • Status changed from New to In Progress
  • Assignee set to Junxiao Shi
  • Target version set to v0.6
Actions #4

Updated by Junxiao Shi almost 7 years ago

  • Status changed from In Progress to Code review
  • % Done changed from 0 to 100

https://gerrit.named-data.net/4032 ensures Name is a RandomAccessRange, a stronger requirement than SinglePassRange.

The problem was:

  • Name::iterator was declared different as Name::const_iterator.
  • Name::begin() has only const variant, so its return type on non-const Name instance differs from Name::iterator.

I solved the problem by declaring Name::iterator as const Component*. This disallows modifying a Component via iterator, which wasn't permitted previously because there wasn't a method returning iterator. This declaration is valid as same is used in std::set.

Actions #5

Updated by Junxiao Shi almost 7 years ago

  • Status changed from Code review to Closed
Actions

Also available in: Atom PDF