Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

range-v3 "ranges::to" not working with "etl::vector" #630

Open
pwhittin opened this issue Nov 2, 2022 · 4 comments
Open

range-v3 "ranges::to" not working with "etl::vector" #630

pwhittin opened this issue Nov 2, 2022 · 4 comments
Assignees

Comments

@pwhittin
Copy link

pwhittin commented Nov 2, 2022

The following short sample program demonstrates the issue:

#include <iostream>
#include <vector>
#include <etl/string.h>
#include <etl/vector.h>
#include <range/v3/all.hpp>

using Name = etl::string<20>;

static constexpr auto ExpandName = [](const auto& name) { return ranges::views::repeat_n(name, 3); };

int main()
{
    {
        using Names = std::vector<Name>;
        auto names{Names{Name{"Fred"}, Name{"Sam"}, Name{"Peter"}}};
        auto expandedNames{names | ranges::views::transform(ExpandName) | ranges::views::join | ranges::to<Names>};
        for (const auto& name : expandedNames)
            std::cout << name.data() << std::endl;
    }

    {
        using Names = etl::vector<Name, 100>;
        auto names{Names{Name{"Fred"}, Name{"Sam"}, Name{"Peter"}}};

         // The following line will not compile
        auto expandedNames{names | ranges::views::transform(ExpandName) | ranges::views::join | ranges::to<Names>};

    }

    return 0;
}

Using ETL 20.35.0 and Range-v3 0.12.0, the error messages from gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0, executing gcc -Ietl/include -Irange-v3/include main.cpp are:

etl/include/etl/iterator.h:64:51: error: no type named ‘iterator_category’ in ‘struct ranges::common_iterator<ranges::basic_iterator<ranges::join_view<ranges::transform_view<ranges::ref_view<etl::vector<etl::stri
ng<20>, 100> >, <lambda(const auto:10&)> > >::cursor<false> >, ranges::default_sentinel_t>’
   64 |     typedef typename TIterator::iterator_category iterator_category;
      |                                                   ^~~~~~~~~~~~~~~~~                                                                                                                                         etl/include/etl/iterator.h:65:51: error: no type named ‘value_type’ in ‘struct ranges::common_iterator<ranges::basic_iterator<ranges::join_view<ranges::transform_view<ranges::ref_view<etl::vector<etl::string<20>,
 100> >, <lambda(const auto:10&)> > >::cursor<false> >, ranges::default_sentinel_t>’
   65 |     typedef typename TIterator::value_type        value_type;
      |                                                   ^~~~~~~~~~             
etl/include/etl/iterator.h:67:51: error: no type named ‘pointer’ in ‘struct ranges::common_iterator<ranges::basic_iterator<ranges::join_view<ranges::transform_view<ranges::ref_view<etl::vector<etl::string<20>, 10
0> >, <lambda(const auto:10&)> > >::cursor<false> >, ranges::default_sentinel_t>’
   67 |     typedef typename TIterator::pointer           pointer;     
      |                                                   ^~~~~~~    
etl/include/etl/iterator.h:68:51: error: no type named ‘reference’ in ‘struct ranges::common_iterator<ranges::basic_iterator<ranges::join_view<ranges::transform_view<ranges::ref_view<etl::vector<etl::string<20>, 
100> >, <lambda(const auto:10&)> > >::cursor<false> >, ranges::default_sentinel_t>’
   68 |     typedef typename TIterator::reference         reference;
@jwellbelove
Copy link
Contributor

Could you try changing line 88 in vector.h from
typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
to
typedef ptrdiff_t difference_type;

@jwellbelove jwellbelove added the bug label Nov 2, 2022
@pwhittin
Copy link
Author

pwhittin commented Nov 2, 2022

I did what you asked:

I executed g++ --std=c++20 -Irange-v3/include/ -Ietl/include/ main.cpp and got these errors:

etl/include/etl/iterator.h:64:51: error: no type named ‘iterator_category’ in ‘struct ranges::common_iterator<ranges::basic_iterator<ranges::join_view<ranges::transform_view<ranges::ref_view<etl::vector<etl::stri
ng<20>, 100> >, <lambda(const auto:28&)> > >::cursor<false> >, ranges::default_sentinel_t>’
   64 |     typedef typename TIterator::iterator_category iterator_category;
      |                                                   ^~~~~~~~~~~~~~~~~                                                                                                                                         etl/include/etl/iterator.h:65:51: error: no type named ‘value_type’ in ‘struct ranges::common_iterator<ranges::basic_iterator<ranges::join_view<ranges::transform_view<ranges::ref_view<etl::vector<etl::string<20>,
 100> >, <lambda(const auto:28&)> > >::cursor<false> >, ranges::default_sentinel_t>’
   65 |     typedef typename TIterator::value_type        value_type;
      |                                                   ^~~~~~~~~~             
etl/include/etl/iterator.h:67:51: error: no type named ‘pointer’ in ‘struct ranges::common_iterator<ranges::basic_iterator<ranges::join_view<ranges::transform_view<ranges::ref_view<etl::vector<etl::string<20>, 10
0> >, <lambda(const auto:28&)> > >::cursor<false> >, ranges::default_sentinel_t>’
   67 |     typedef typename TIterator::pointer           pointer;     
      |                                                   ^~~~~~~    
etl/include/etl/iterator.h:68:51: error: no type named ‘reference’ in ‘struct ranges::common_iterator<ranges::basic_iterator<ranges::join_view<ranges::transform_view<ranges::ref_view<etl::vector<etl::string<20>, 
100> >, <lambda(const auto:28&)> > >::cursor<false> >, ranges::default_sentinel_t>’
   68 |     typedef typename TIterator::reference         reference;

Just to be sure I executed head -n 90 etl/include/etl/vector.h | tail -n 26 in the project directory, and got:

//***************************************************************************
/// The base class for specifically sized vectors.
/// Can be used as a reference type for all vectors containing a specific type.
///\ingroup vector
//***************************************************************************
template <typename T>
class ivector : public etl::vector_base
{
  public:
    typedef T value_type;
    typedef T& reference;
    typedef const T& const_reference;
#if ETL_USING_CPP11
    typedef T&& rvalue_reference;
#endif
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T* iterator;
    typedef const T* const_iterator;
    typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
    typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
    // typedef typename etl::iterator_traits<iterator>::difference_type difference_type;

  protected:

@jwellbelove
Copy link
Contributor

It looks like the ETL may need a specialisation of etl::iterator_traits for std::common_iterator.

https://en.cppreference.com/w/cpp/iterator/common_iterator/iterator_traits

@StjerneIdioten
Copy link

I ran into a similar issuing trying to use etl::copy_s with std::counted_iterator. The cppreference page for std::iterator_traits<std::counted_iterator> seems to have more information. This iterator comes with a function for accessing the base iterator, so I used that whenever I had to interact with ETL functions to get around this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

No branches or pull requests

3 participants