Range library for C++14/17/20, basis for C++20's std::ranges

range-v3

Range library for C++14/17/20. This code was the basis of a formal proposal to add range support to the C++ standard library. That proposal evolved through a Technical Specification, and finally into P0896R4 "The One Ranges Proposal" which was merged into the C++20 working drafts in November 2018.

About:

Ranges are an extension of the Standard Template Library that makes its iterators and algorithms more powerful by making them composable. Unlike other range-like solutions which seek to do away with iterators, in range-v3 ranges are an abstration layer on top of iterators.

Range-v3 is built on three pillars: Views, Actions, and Algorithms. The algorithms are the same as those with which you are already familiar in the STL, except that in range-v3 all the algorithms have overloads that take ranges in addition to the overloads that take iterators. Views are composable adaptations of ranges where the adaptation happens lazily as the view is iterated. And an action is an eager application of an algorithm to a container that mutates the container in-place and returns it for further processing.

Views and actions use the pipe syntax (e.g., rng | adapt1 | adapt2 | ...) so your code is terse and readable from left to right.

Documentation:

Check out the (woefully incomplete) documentation here.

Other resources (mind the dates, the library probably has changed since then):

License:

Most of the source code in this project are mine, and those are under the Boost Software License. Parts are taken from Alex Stepanov's Elements of Programming, Howard Hinnant's libc++, and from the SGI STL. Please see the attached LICENSE file and the CREDITS file for the licensing and acknowledgments.

Supported Compilers

The code is known to work on the following compilers:

  • clang 5.0 (or later)
  • GCC 6.5 (or later)
  • Clang/LLVM 6 (or later) on Windows (older versions may work - we haven't tested.)
  • Visual Studio 2019 (or later) on Windows, with some caveats due to range-v3's strict conformance requirements:
    • range-v3 needs /permissive- and either /std:c++latest or /std:c++17

Development Status: This code is fairly stable, well-tested, and suitable for casual use, although currently lacking documentation. In general, no promise is made about support or long-term stability. This code will evolve without regard to backwards compatibility.

A notable exception is anything found within the ranges::cpp20 namespace. Those components will change rarely or (preferably) never at all.

Build status

  • on GitHub Actions: GitHub Actions Status

Building range-v3 - Using vcpkg

You can download and install range-v3 using the vcpkg dependency manager:

git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install range-v3

The range-v3 port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please create an issue or pull request on the vcpkg repository.

Building range-v3 - Using Conan

You can download and install range-v3 using the Conan dependency manager.

Setup your CMakeLists.txt (see Conan documentation on how to use MSBuild, Meson and others):

project(myproject CXX)

add_executable(${PROJECT_NAME} main.cpp)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) # Include Conan-generated file
conan_basic_setup(TARGETS) # Introduce Conan-generated targets

target_link_libraries(${PROJECT_NAME} CONAN_PKG::range-v3)

Create conanfile.txt in your source dir:

[requires]
range-v3/0.10.0

[generators]
cmake

Install and run conan, then build your project as always:

pip install conan
mkdir build
cd build
conan install ../ --build=missing
cmake ../
cmake --build .

Building range-v3 - Using build2

You can use build2, a dependency manager and a build-system combined, to use range-v3 (or work on it):

Currently this package is available in these package repositories:

Usage:

For example, to make your build2 project depend on range-v3:

  • Add one of the repositories to your configurations, or in your repositories.manifest, if not already there; for example:
    :
    role: prerequisite
    location: https://pkg.cppget.org/1/alpha # v0.11.0 is there.
    
  • Add this package as a dependency to your manifest file (example for v0.11.x):
    depends: range-v3 ~0.11.0
    
  • Import the target and use it as a prerequisite to your own target using range-v3 in the appropriate buildfile:
    import range_v3 = range-v3%lib{range-v3}
    
    lib{mylib} : cxx{**} ... $range_v3
    

Then just build your project as usual (with b or bdep update), build2 will figure out the rest.

For build2 newcomers or to get more details and use cases, you can read this document and the build2 toolchain introduction.

Say Thanks!

I do this work because I love it and because I love C++ and want it to be as excellent as I know it can be. If you like my work and are looking for a way to say thank you, you can leave a supportive comment on my blog. Or you could leave me some kudos on my Open Hub range-v3 contribution page. Just click the Give Kudos button here.

Owner
Eric Niebler
Member of the ISO C++ Standardization Committee and principal author of the Ranges TS.
Eric Niebler
Comments
  • `const`-ness of view operations

    `const`-ness of view operations

    Containers

    Containers in C++ may have both const and non-const overloads of begin. They differ only in their return types: non-const begin returns a mutable iterator, and const begin a constant iterator. Neither overload changes the bits of the container representation or modifies the semantic value of the container object. Two overloads exist so that it is necessary to establish a non-const access path to the container object in order to obtain a mutable iterator. end is the same. size is always const because it provides no way to modify the container's content.

    Views

    Views in range-v3 may have both const and non-const overloads of begin/end/size (herein termed "operations"). Views have pointer semantics - a view is essentially a pointer to a sequence of elements - so mutability of the elements viewed is orthogonal to mutability of the view object itself. The const distinction here has no relation to that of containers. Non-const operations do not modify the semantic objects being viewed, nor do they "swing the pointer" so that the same view designates different semantic objects. Non-const operations mutate internal state that does not contribute to the semantic value of the view; the const-ness here is purely bitwise.

    The const-ness model used by views makes view composition painful. You can always provide the non-const overloads, but const overloads are preferred when achievable. So a composer, e.g.:

    template<typename View>
    class wrap_view : view_facade<wrap_view<View>>
    {
        View base_;
    public:
        wrap_view() = default;
        wrap_view(View v)
        : base_(std::move(v))
        {}
        // ...
    };
    

    ends up providing two definitions of each operation: one const that's constrained to require const operations over the underlying view(s):

        // We need the dependent type V so that range_iterator_t<V const> doesn't hard
        // error when View has no const begin operation (or: use C++14 deduced return type).
        template <typename V = View, CONCEPT_REQUIRES_(Range<View const>())>
        range_iterator_t<V const> begin() const
        { return ranges::begin(base_); }
    

    and one mutable that's constrained to only be available when the const version isn't:

        CONCEPT_REQUIRES(!Range<View const>())
        range_iterator_t<View> begin()
        { return ranges::begin(base_); }
    

    Ranges

    I'm concerned that the differing const distinctions for containers and views don't mesh well into a consistent notion of what const means for operations on general ranges. I see a potential for latent bugs where a programmer accustomed to the fact that calling begin/end on mutable containers is threadsafe calls begin/end on mutable ranges without realizing there are sharp corners here.

    The only mutating operation on pointers is assignment. If views are supposed to be range-pointers, perhaps assignment should be the only mutating operation? We (I) need to investigate an alternative model where view operations are always const and perform internal synchronization if needed.

  • [cmake/travis] refactor/improve CMake; add MSan/LSan builds in travis

    [cmake/travis] refactor/improve CMake; add MSan/LSan builds in travis

    • Adds MemorySanitizer and LeakSanitizer (under ASan) in travis:

      • Builds libc++ with MemorySanitizer and AddressSanitizer as required.
      • Enables the leak sanitizer on AddressSanitizer builds under Linux.
      • Enables the unsigned-integer overflow check in the UndefinedBehaviorSanitizer:
        • Avoids overflow in view.unique tests (not a bug).
        • Add RANGES_INTENDED_MODULO_ARITHMETIC macro to explicitly annotate when modulo arithmetic is intended.
        • Explicitly annotates those parts of range-v3 in which modulo arithmetic is intended (mostly in utility/random.hpp).
    • Refactor the root CMakeLists.txt into:

      • cmake/readme.md: brief explanation of what goes where.
      • cmake/ranges_options.cmake: library configuration options.
      • cmake/ranges_env.cmake: detects environment (os, compiler, build type...).
      • cmake/ranges_flags.cmake: sets up supported compiler flags.
    • AppVeyor and Clang/C2 (by @CaseyCarter):

      • Add cmake to PATH in appveyor.yml.
      • Disable -fstruct-vtable-pointers on Clang/C2.
    • Add RANGES_NATIVE option (defaults to On) to allow disabling -march/mtune=native independently of the build-type.

    • Disables std::auto_ptr in boost (not available in C++1z).

    • Add travis build bots for clang-4.0 in C++11 and C++14.

    • Tests clang versions with the corresponding libc++ version (they were always tested with libc++ trunk).

    Closes #333: the ASAN errors reported there cannot be reproduced anymore. Closes #451: -Wnoexcept should be part of -Weverything. Closes #640: clang versions are tested with appropriate libc++ version.

    Thanks @CaseyCarter for the comments, help, and all the Clang/C2 and AppVeyor fixes.

  • view::cycle

    view::cycle

    Turns a finite ForwardRange into an infinite range that cycles on itself.

    Example

    auto il = {0, 1, 2};
    RANGES_FOR(auto i, il | view::cycle) { std::cout << i << " "; }
    

    prints "0 1 2 0 1 2 0 1 2 0 1 2...".

    Notes on the design

    This designs chooses to make two iterators compare equal only if they point to the same element of the sequence within the same cycle. Example: in the sequence above both iterators begin and begin + 3 point to the same element (0); since they are "in different cycles" they are not equal.

    The rationale is that this allows iterating from [begin, begin + M) where M is larger than the number of elements in the sequence.

    TODO

    • The implementation of cycled_view<Rng>::cursor<IsConst>::advance is pretty ugly.
    • The implementation of cycled_view<Rng>::cursor can be optimized for RandomAccessRanges where the iterator can be obtained from the position in O(1).
  • Why is filter deprecated?

    Why is filter deprecated?

    I find both filter and remove_if useful. Replacing filter(pred) with remove_if(not(pred)) makes IMO the code less readable. The intent is just harder to understand due to the double negation: do something on the elements that are not the elements for which the predicate is not true (my brain melts).

  • Proposal: enumerated range

    Proposal: enumerated range

    I find myself doing the following quite often:

    for (const auto& [i, e]: rsv::zip(rsv::iota(0, es.size()), es)) { /* use i, e */ }
    

    This to my mind is more explicit, and leaves less room for mistakes, than:

    for (auto i = 0; i < es.size(); ++i) { /* use i, es[i] */ }
    

    If this idiom is a bad idea, I would appreciate being told why. If not, I think this would be a good candidate for addition to the library, because it is frequently the case that one wants to know the index of the item one is iterating over.

    In my code, I call this enumerated(es), but I'm not particularly attached to this name.

  • Compilation failure because GCC _Safe_iterator meets SizedIteratorRange concept

    Compilation failure because GCC _Safe_iterator meets SizedIteratorRange concept

    I'm getting a compilation failure that I think stems from a (GCC _GLIBCXX_DEBUG) bidirectional iterator meeting the SizedIteratorRange concept and then failing when range-v3 actually uses an expression like itr_a - itr_b.

    I'm guessing the troublesome subtlety may be: the iterator is actually a GCC _Safe_iterator, which does provide an operator-() but which just implements this by passing through to the wrapped std::list iterator that doesn't provide an operator-(). Hence I'm guessing the concepts::same_type(s - i, i - s) line in the SizedIteratorRange concept is checking that the iterator's operator-() exists and has a valid return type but isn't checking that a call to that expression is actually valid. Hence SizedIteratorRange isn't spotting that itr_a - itr_b isn't a valid expression and so doesn't get itself SFINAE-rejected as it should.

    Some illustrative code:

    #define _GLIBCXX_DEBUG
    #define RANGES_NO_STD_FORWARD_DECLARATIONS
    
    #include <iostream>
    #include <list>
    #include <type_traits>
    
    #include <range/v3/all.hpp>
    
    int main() {
        // Background context:
        // Under _GLIBCXX_DEBUG, list returns a list iterator wrapped in a _Safe_iterator
        // whose iterator_category is bidirectional_iterator_tag
        using my_range_type  = std::list< int >;
        using my_iter_type   = decltype( std::begin( std::declval< my_range_type >() ) );
        static_assert(
            std::is_same<
                std::iterator_traits<my_iter_type>::iterator_category,
                std::bidirectional_iterator_tag
            >::value,
            ""
        );
    
        // Background context:
        // range-v3 identifies the _Safe_iterator<...> as SizedIteratorRange
        using rv3_iterator_t = ranges::range_iterator_t< my_range_type >;
        using rv3_sentinel_t = ranges::range_sentinel_t< my_range_type >;
        using rv3_sirc_t     = ranges::sized_iterator_range_concept<rv3_iterator_t,
                                                                    rv3_sentinel_t>;
        ranges::concepts::SizedIteratorRange * my_ptr = rv3_sirc_t();
    
        //  **** PROBLEM HERE *****
        // Fails to compile the '...::take( 3 );' line.
        // I think that's because range-v3 treats _Safe_iterator<...> as a
        // SizedIteratorRange iterator but then cannot subtract one from another
        // (because that's not supported by the underlying list iterator)
        const my_range_type my_values = { 1, 2, 3, 4 };
        const auto my_first_values = my_values | ranges::v3::view::take( 3 );
        std::cerr << *ranges::max_element( my_first_values ) << "\n";
    
        return 0;
    }
    

    Compile command:

    g++ -std=c++11 -isystem range-v3/include -ftemplate-backtrace-limit=0 rv3_safe_iter_prob.cpp
    

    (also works with -std=c++14; -ftemplate-backtrace-limit=0 avoids clipped messages)

  • Find a better name for iterator_range

    Find a better name for iterator_range

    Especially when dealing with old/current interfaces you sometimes have a pair of begin/end iterators you have to deal with. It would be great if I could e.g. view::all_between(it, it_end) | view::join | ...

    Does something like this exist and I just overlooked it? If not, do you agree, it would be nice to have? I could look into it and maybe create a PR...

  • Uniform namespace conventions between Meta and Range/utility/Meta

    Uniform namespace conventions between Meta and Range/utility/Meta

    I'm trying to make Range work bootstrapping Meta into it first, instead of having (maintaining) both copies of the same library. My idea is to make this change least intrusive possible. Given the current meta.hpp file in range, what I'm doing is:

    #if defined(BIICODE)
    #include <meta/meta.hpp>
    #else
    #include <type_traits>
    #include <initializer_list>
    #include <range/v3/utility/nullptr_v.hpp>
    #include <range/v3/utility/static_const.hpp>
    ...
    

    The dependency works perfectly, but I'm not able to compile since Meta and Range are using different namespaces to declare/define Meta features. Relying on sorcery like #include inside a nested namespace is not a solution for me, neither for you I guess (Ignoring that trick would potentially generate name issues with STL things etc).

    Maybe we can study the effort neccesary to unify both naming conventions.

  • Add view::shared

    Add view::shared

    Description: view::shared was designed to allow the construction of temporary containers in the middle of the range pipeline (such as inside view::for_each or view::transform). Such temporary containers can be afterwards used in the remaining part of the pipeline, without the danger of dangling references. view::shared allows elegant constructions, which would be otherwise very difficult to express and the code readability would be significantly degraded (see examples at the end of this description).

    Internally, view::shared stores only std::shared_ptr to the underlying range, and therefore construction, destruction, copying and moving of view::shared are still O(1)-time operations, except for the last destruction, which can take up to O(N) time. The linear complexity of the last destruction, however, can be amortized with the time needed to construct the underlying container.

    It can be constructed:

    • from an rvalue reference of a range
    • from std::shared_ptr of a range
    • as a function
    • as a range pipeline element

    Example 1: Apply a transformation function returning a vector, to a range of integers, and flatten the result.

    std::vector<int> foo(int a);
    auto rng =
        view::iota(1)
      | view::transform(foo)
      | view::transform(view::shared)
      | view::join;
    

    Example 2: Build a range which repeats the numbers from a pre-specified vector, but in each epoch, the numbers are randomly shuffled (as is usual e.g., for the training data in machine learning).

    std::vector<int> base{5, 1, 8};
    auto rng =
        view::repeat(base)
      | view::for_each([](std::vector<int> tmp) {
            return std::move(tmp)
                 | action::shuffle(gen)
                 | view::shared;
        });
    

    Stand-alone views: Naturally, view::shared can be used to encapsulate the initial data structure inside a view without bothering with the structure's scope. Therefore, it allows the creation of stand-alone views inside of functions:

    auto build_view()
    {
        std::vector<int> base{5, 1, 8};
        return std::move(base) | view::shared | ...
    }
    
  • Taking distance() of const ref to view::remove_if fails to compile

    Taking distance() of const ref to view::remove_if fails to compile

    Taking the distance() of a const-lvalue-reference to a view::remove_if fails to compile under both GCC and Clang because it attempts to calculate a type using ranges::range_difference_t<T>, which fails as illustrated in this example:

    #include <range/v3/all.hpp>
    
    int main() {
        int rg[] = { 1, 2, 3, 4, 5 };
    
        // This     const view::tail      is fine
        const auto const_tail_view        = rg | ranges::view::tail;
        using      const_tail_view_diff_t = ranges::range_difference_t< decltype( const_tail_view ) >;
    
        // This non-const view::remove_if is fine
              auto even_view              = rg | ranges::view::remove_if( [] (const int &i) { return ( i % 2 == 0 ); } );
        using      even_view_diff_t       = ranges::range_difference_t< decltype( even_view ) >;
    
        // This     const view::remove_if fails to compile
        const auto const_even_view        = rg | ranges::view::remove_if( [] (const int &i) { return ( i % 2 == 0 ); } );
        using      const_even_view_diff_t = ranges::range_difference_t< decltype( const_even_view ) >;
    
        return 0;
    }
    

    My understanding is that this attempts to compute the type of begin(std::declval<T&>()), which leads to a failed instantiation of the begin_fn::operator()() template, which then fails because neither private impl() function can be used.

    I've found that this problem occurs with both view::remove_if and view::drop_while but not with:

    • view::adjacent_remove_if
    • view::chunk
    • view::delimit
    • view::drop
    • view::replace
    • view::reverse
    • view::slice
    • view::stride
    • view::tail
    • view::take
    • view::take
    • view::take_exactly
    • view::take_while
  • fix missing includes forever

    fix missing includes forever

    All kudos go to Louis Dione for writing the CMake scripts of Boost.Hana.

    This just adapts his scripts for range-v3; all mistakes introduced are only mine.

    • fix missing includes caught by the tests.
    • replace # warning with #pragma message because -Werror, -Wpedantic complains that # warning is a language extension (this prevents some new tests from compiling).

    Closes #182 .

  • Allow collecting into std::array if the size is known

    Allow collecting into std::array if the size is known

    I couldn't find any discussion from a quick search in the issues, but have you considered collecting a result from a range into a std::array?

    I understand it's not currently supported since std::array is an aggregate and doesn't have user-defined constructors to accept the ranges/iterators (beyond the obvious reason that for many ranges we can't expect to know the size at compile-time).

    That being said, and while I don't know the intricacies of the ranges::to<>, nor do I have extensive knowledge of C++ templates, I toyed around and made it do what I want in a simple case (see on Compiler Explorer).

    But I figured it would be good to hear from someone more experienced with the library and its internals.

  • Concept error: satisfaction of atomic constraint '__is_constructible(T) [with Args = {I}; T = I]' depends on itself

    Concept error: satisfaction of atomic constraint '__is_constructible(T) [with Args = {I}; T = I]' depends on itself

    Hi,

    the following concepts cause a cryptic error within the range-v3 v.0.12 library when used with GCC-11 or GCC-12 (linux):

    template < typename MapLike >
    concept mapping = requires(MapLike m) {
                         // has to be key-value-like to iterate over values and keys only repsectively
                         ranges::views::keys(m);
                         ranges::views::values(m);
                      };
    
    template < typename MapLike, typename KeyType >
    concept maps = mapping< MapLike >
                   and std::is_convertible_v<    // value type has to be convertible to the Mapped Type
                      decltype(*(ranges::views::keys(std::declval< MapLike >()).begin())),
                      KeyType >;
    

    the error message goes deep within the range-v3 concepts:

    /opt/compiler-explorer/libs/rangesv3/0.12.0/include/range/v3/view/all.hpp: In instantiation of 'constexpr auto ranges::views::all_fn::operator()(T&&) const [with T = const Hashmap&]': /opt/compiler-explorer/libs/rangesv3/0.12.0/include/range/v3/view/all.hpp:91:35: required by substitution of 'template requires (viewable_range) && (input_range) && (kv_pair_like_<decltype((declval<decltype(ranges::_::begin(static_cast<Rng& ()()noexcept (true)>(nullptr)()))&>)())>) ranges::keys_range_view<decltype (ranges::views::all(declval()))> ranges::views::keys_fn::operator()(Rng&&) const [with Rng = const Hashmap&]'

    :15:41: required by substitution of 'template requires maps Hashmap::Hashmap(U&&) [with U = int]' /opt/compiler-explorer/libs/rangesv3/0.12.0/include/concepts/concepts.hpp:1153:13: required from 'constexpr auto ranges::views::all_fn::operator()(T&&) const [with T = Hashmap&]' /opt/compiler-explorer/libs/rangesv3/0.12.0/include/range/v3/view/all.hpp:91:35: required by substitution of 'template requires (viewable_range) && (input_range) && (kv_pair_like_(nullptr)()))&>)())>) ranges::values_view()))> ranges::views::values_fn::operator()(Rng&&) const [with Rng = Hashmap&]' /opt/compiler-explorer/libs/rangesv3/0.12.0/include/range/v3/functional/invoke.hpp:140:34: required by substitution of 'template constexpr decltype ((F&&)(f)((Args&&(ranges::invoke_fn::operator()::args))...)) ranges::invoke_fn::operator()(F&&, Args&& ...) const [with F = ranges::views::values_fn; Args = {Hashmap&}]' /opt/compiler-explorer/libs/rangesv3/0.12.0/include/range/v3/functional/concepts.hpp:40:5: required by substitution of 'template requires (viewable_range) && (invocable_view_closure) constexpr auto ranges::views::view_closure_base_ns::operator|(Rng&&, ranges::views::view_closure) [with Rng = Hashmap&; ViewFn = ranges::views::values_fn]' :60:36: required from here /opt/compiler-explorer/libs/rangesv3/0.12.0/include/concepts/concepts.hpp:1151:21: required for the satisfaction of 'constructible_from' [with T = Hashmap] /opt/compiler-explorer/libs/rangesv3/0.12.0/include/concepts/concepts.hpp:1170:9: required for the satisfaction of 'copy_constructible_concept_' [with T = Hashmap] /opt/compiler-explorer/libs/rangesv3/0.12.0/include/concepts/concepts.hpp:1181:21: required for the satisfaction of 'copy_constructible' [with T = Hashmap] /opt/compiler-explorer/libs/rangesv3/0.12.0/include/concepts/concepts.hpp:1209:21: required for the satisfaction of 'copyable' [with T = Hashmap] /opt/compiler-explorer/libs/rangesv3/0.12.0/include/concepts/concepts.hpp:1217:21: required for the satisfaction of 'semiregular' [with T = Hashmap] cc1plus: error: satisfaction of atomic constraint '__is_constructible(T) [with Args = {const I}; T = I]' depends on itself /opt/compiler-explorer/libs/rangesv3/0.12.0/include/concepts/concepts.hpp:1151:21: required for the satisfaction of 'constructible_from' [with T = Hashmap] /opt/compiler-explorer/libs/rangesv3/0.12.0/include/concepts/concepts.hpp:1170:9: required for the satisfaction of 'copy_constructible_concept_' [with T = Hashmap] /opt/compiler-explorer/libs/rangesv3/0.12.0/include/concepts/concepts.hpp:1181:21: required for the satisfaction of 'copy_constructible' [with T = Hashmap] /opt/compiler-explorer/libs/rangesv3/0.12.0/include/concepts/concepts.hpp:1209:21: required for the satisfaction of 'copyable' [with T = Hashmap] /opt/compiler-explorer/libs/rangesv3/0.12.0/include/concepts/concepts.hpp:1217:21: required for the satisfaction of 'semiregular' [with T = Hashmap] cc1plus: error: satisfaction of atomic constraint '__is_constructible(T) [with Args = {const I}; T = I]' depends on itself

    I am using this concept in my code to filter out maps over certain key types (maybe this isn't the best way) and this error has been bugging me for a while now.

    Here is a godbolt link to verify the problem on GCC 11/12. It does work e.g. under clang 15: https://godbolt.org/z/dqj1YY9e4

    The problem does not exist with std::ranges and GCC, but it does for clang now: https://godbolt.org/z/a88WMe66b

  • drop_while view and sorted range : possible optimization?

    drop_while view and sorted range : possible optimization?

    Hi, Reading drop_while page I think it would be handy to be able to tell that we are iterating an already sorted range, when applicable.

    Right now, it seems to iterate every elements, whereas it could use a binary search to go faster.

  • Extremely cryptic error message - bug?

    Extremely cryptic error message - bug?

    This error message has two problems:

    1. It doesn't mention my offending line of code.
    2. It's so cryptic that I can't decipher what it's complaining about.

    I get that template C++ error messages are difficult but this seems like it might be far enough to be considered a bug.

    Perhaps it's specific to the compiler. I'm using Clang 15.0.1

    #include <iostream>
    #include <vector>
    #include <range/v3/all.hpp>
    
    int main(int argc, char *argv[])
    {
        namespace rv = ranges::views;
        std::vector<int> points = {10,11,12,13};
        // This is what I meant:
        // auto point_idxs = rv::concat( rv::iota(0, (int)points.size()), rv::single(0) );
        // But I wrote this:
        auto point_idxs = rv::concat( rv::iota(points.size()), rv::single(0) );    
        for (auto chunk : point_idxs | rv::sliding(2)) {
            std::cout << chunk << "\n";
        }
        return 0;
    }
    

    The error message is attached.

    error.txt

  • Access n-th in a view

    Access n-th in a view

    Hi, I would like to use range but without a for loop.

    auto view_ = my_container | ::ranges::views::cycle | ::ranges::views::take( my_container.size() + 1 ) | ::ranges::views::drop( drop_count );
    for ( auto &e : view_ ){/*do something*/; break; }
    

    I would like to iterate "a la coroutine" my view manually as in view_() or something of the like. That would give me the current value and increase the internal counter to the next element.

    That would enable me to play with multiple views. So, if my_container is vector<int> a{0,1,2,3}, I would have

    view_(0); // 0 with  starting offset, here 0
    view_(); // 1 and so on taking the cycle into account 
    

    Right now, I have to recreate my view with a new drop_count value, which seems inefficient.

    How to achieve that cleanly?

    Thanks

  • ranges::sort does not work with Qt 5 QList

    ranges::sort does not work with Qt 5 QList

    Debian 11 gcc (Debian 10.2.1-6) Ranges 0.11.0 Qt 5.15.10 -std=gnu++2a

    If I have code like this:

        QList<int> l;
        ranges::sort(l);
    

    I get:

    /somewhere/code.cpp: In function ‘QStringList {anonymous}::detail::uniqueVideoSourceTokens(const QList<vtg::onvif::OnvifMediaProfileInfo>&)’:
    /somewhere/code.cpp:103:19: error: no match for call to ‘(const ranges::sort_fn) (QList<int>&)’
      103 |     ranges::sort(l);
          |                   ^
    In file included from /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/range_fwd.hpp:25,
                     from /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/view/filter.hpp:17,
                     from /somewhere/code.cpp:18:
    /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/algorithm/sort.hpp:201:11: note: candidate: ‘template<class I, class S, class C, class P>  requires (sortable<I, C, P>) && (random_access_iterator<I>) && (sentinel_for<S, I>) I ranges::sort_fn::operator()(I, S, C, P) const’
      201 |         I RANGES_FUNC(sort)(I first, S end_, C pred = C{}, P proj = P{})
          |           ^~~~~~~~~~~
    /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/algorithm/sort.hpp:201:11: note:   template argument deduction/substitution failed:
    /somewhere/code.cpp:103:19: note:   candidate expects 4 arguments, 1 provided
      103 |     ranges::sort(l);
          |                   ^
    In file included from /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/range_fwd.hpp:25,
                     from /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/view/filter.hpp:17,
                     from /somewhere/code.cpp:18:
    /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/algorithm/sort.hpp:218:9: note: candidate: ‘ranges::borrowed_iterator_t<Rng> ranges::sort_fn::operator()(Rng&&, C, P) const [with Rng = QList<int>&; C = ranges::less; P = ranges::identity; ranges::borrowed_iterator_t<Rng> = QList<int>::iterator]’
      218 |         RANGES_FUNC(sort)(Rng && rng, C pred = C{}, P proj = P{}) //
          |         ^~~~~~~~~~~
    /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/algorithm/sort.hpp:218:9: note: constraints not satisfied
    In file included from /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/range_fwd.hpp:22,
                     from /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/view/filter.hpp:17,
                     from /somewhere/code.cpp:18:
    /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/iterator/concepts.hpp: In instantiation of ‘ranges::borrowed_iterator_t<Rng> ranges::sort_fn::operator()(Rng&&, C, P) const [with Rng = QList<int>&; C = ranges::less; P = ranges::identity; ranges::borrowed_iterator_t<Rng> = QList<int>::iterator]’:
    /somewhere/code.cpp:103:19:   required from here
    /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/iterator/concepts.hpp:291:5:   required for the satisfaction of ‘sized_sentinel_for__requires_<S, I>’ [with S = QList<int>::iterator<int>; I = QList<int>::iterator<int>]
    /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/iterator/concepts.hpp:305:17:   required for the satisfaction of ‘sized_sentinel_for<I, I>’ [with I = QList<int>::iterator<int>]
    /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/iterator/concepts.hpp:371:17:   required for the satisfaction of ‘random_access_iterator<decltype (ranges::_::begin(declval<Rng&>()))>’ [with Rng = QList<int>&]
    /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/range/concepts.hpp:106:5:   required for the satisfaction of ‘random_access_range__concept_<T>’ [with T = QList<int>&]
    /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/range/concepts.hpp:112:17:   required for the satisfaction of ‘random_access_range<Rng>’ [with Rng = QList<int>&]
    /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/iterator/concepts.hpp:291:5:   in requirements with ‘const S& s’, ‘const I& i’ [with _Arg = QList<int>::iterator<int>; I = QList<int>::iterator<int>; S = QList<int>::iterator<int>]
    /home/user/.conan/data/range-v3/0.11.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/range/v3/iterator/concepts.hpp:291:5: note: the required expression ‘((((s - i), (i - s)), requires_<same_as<typename ranges::incrementable_traits<typename std::remove_cv<meta::_t<std::remove_reference<_Arg> > >::type>::difference_type, decltype ((s - i))> >), requires_<same_as<typename ranges::incrementable_traits<typename std::remove_cv<meta::_t<std::remove_reference<_Arg> > >::type>::difference_type, decltype ((i - s))> >)’ is invalid
      291 |     CPP_requires(sized_sentinel_for_,
          |     ^~~~~~~~~~~~
    cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more detail
    

    But std::sort(l.begin(), l.end()) works.

    For some reason ranges::sort does not "like" QList<>::iterator?

    Qt docs states that it's random access iterator: https://doc.qt.io/qt-5/qlist-iterator.html#iterator_category-typedef

A BOF to parse the imports of a provided PE-file, optionally extracting symbols on a per-dll basis.

PE Import Enumerator BOF What is this? This is a BOF to enumerate DLL files to-be-loaded by a given PE file. Depending on the number of arguments, thi

Nov 9, 2022
Basis Universal GPU Texture Codec
Basis Universal GPU Texture Codec

basis_universal Basis Universal Supercompressed GPU Texture Codec Basis Universal is a "supercompressed" GPU texture data interchange system that supp

Nov 30, 2022
Single-header, ranges-compatible generator type built on C++20 coroutines

generator Single-header, ranges-compatible generator type built with C++20 coroutines. A generator allows implementing sequence producers which are te

Nov 16, 2022
Ranges that didn't make C++20

ranges Implementations of ranges that didn't make C++20. Coded live on Twitch. Types tl::enumerate_view/tl::views::enumerate A view which lets you ite

Nov 28, 2022
Companion source code for "Programming with C++20 - Concepts, Coroutines, Ranges, and more"
Companion source code for

Companion Source Code for "Programming with C++20 - Concepts, Coroutines, Ranges, and more" 1. Edition Code examples This repository contains runnable

Nov 24, 2022
An Arduino library which allows you to communicate seamlessly with the full range of u-blox GNSS modules
An Arduino library which allows you to communicate seamlessly with the full range of u-blox GNSS modules

u-blox makes some incredible GNSS receivers covering everything from low-cost, highly configurable modules such as the SAM-M8Q all the way up to the surveyor grade ZED-F9P with precision of the diameter of a dime.

Nov 21, 2022
A C++ concepts and range based character encoding and code point enumeration library

Travis CI (Linux:gcc) Text_view A C++ Concepts based character encoding and code point enumeration library. This project is the reference implementati

Sep 9, 2022
A header-only C++ library that enables the representation of a range of values in a linear space

Numeric Range A header-only C++ library that enables the representation of a range of values in a linear space (via the NumericRange class). The linea

Mar 22, 2022
RemixDB: A read- and write-optimized concurrent KV store. Fast point and range queries. Extremely low write-amplification.

REMIX and RemixDB The REMIX data structure was introduced in paper "REMIX: Efficient Range Query for LSM-trees", FAST'21. This repository maintains a

Dec 3, 2022
An efficient, composable design pattern for range processing
An efficient, composable design pattern for range processing

Transrangers An efficient, composable design pattern for range processing. Intro Pull-based approach Push-based approach Transrangers Performance Tran

Nov 10, 2022
ZTE Nubia Z17 (codenamed "nx563j") is a high-range smartphone from Nubia.
ZTE Nubia Z17 (codenamed

ZTE Nubia Z17 (codenamed "nx563j") is a high-range smartphone from Nubia. It was released in June 2017.

Oct 25, 2021
Dynamic array supporting Range Minimum Queries

dynamic-RMQ Dynamic array supporting Range Minimum Queries. Data structure that represent a dynamic array supporting Range Minimum Queries. The data s

Aug 24, 2022
Packages for simulating the Tethys-class Long-Range AUV (LRAUV) from the Monterey Bay Aquarium Research Institute (MBARI).
Packages for simulating the Tethys-class Long-Range AUV (LRAUV) from the Monterey Bay Aquarium Research Institute (MBARI).

LRAUV Simulation This repository contains packages for simulating the Tethys-class Long-Range AUV (LRAUV) from the Monterey Bay Aquarium Research Inst

Nov 24, 2022
Playbit System interface defines an OS-like computing platform which can be implemented on a wide range of hosts

PlaySys The Playbit System interface PlaySys defines an OS-like computing platform which can be implemented on a wide range of hosts like Linux, BSD,

Dec 1, 2022
SX1276/77/78/79 Low Power Long Range Transceiver driver for esp-idf
SX1276/77/78/79 Low Power Long Range Transceiver driver for esp-idf

esp-idf-sx127x SX1276/77/78/79 Low Power Long Range Transceiver driver for esp-idf. I based on this. Changes from the original Added support for ESP32

Nov 30, 2022
SX1262//68 Low Power Long Range Transceiver driver for esp-idf
SX1262//68 Low Power Long Range Transceiver driver for esp-idf

esp-idf-sx126x SX1262//68 Low Power Long Range Transceiver driver for esp-idf. I ported from here. Ai-Thinker offers several LoRa modules. You can get

May 9, 2022
high performance C++20 implementation of std::variant

A minimal compile-time overhead, C++20 implementation of std::variant. Fully standard conforming with a couple of documented differences.

Nov 22, 2022
A cleaner and more intuitive std::variant alternative

[WIP] ExtendedVariant This single header library is part of my C++ extended standard stdex libraries. Check our my profile for more. Working with C++

Jun 13, 2021
std::find simd version
std::find simd version

std::find simd version std::find doesn't use simd intrinsics. ( check https://gms.tf/stdfind-and-memchr-optimizations.html ) So i thought simd can mak

Oct 19, 2022