Coder Social home page Coder Social logo

tcbrindle / nanorange Goto Github PK

View Code? Open in Web Editor NEW
354.0 23.0 26.0 1.79 MB

Range-based goodness for C++17

License: Boost Software License 1.0

CMake 1.29% C++ 98.51% Ruby 0.06% Python 0.14%
cplusplus cplusplus-20 range ranges-proposal concepts

nanorange's Introduction

Standard License Build Status Build status download Try it on godbolt online

NanoRange

NanoRange is a C++17 implementation of the C++20 Ranges proposals (formerly the Ranges TS). It provides SFINAE-based implementations of all the proposed Concepts, and constrained and range-based versions the algorithms in the <algorithm> standard library header.

It is intended for users who want range-based goodness in their C++, but don't want to (or can't) use the full-blown Range-V3. It also aims to provide an easy upgrade path to standard ranges when they arrive.

NanoRange is compatible with all three major C++ compilers, including the latest version of Microsoft Visual C++.

Usage

The easiest way to use NanoRange is to simply download the latest, automatically-generated single-header version and include it in your own sources like any other header. This is currently the recommended way to use the library.

Alternatively, you can clone this repository and use the individual headers in the include/nanorange directory. This may give a slight boost to compile times, although there doesn't seem to be too much difference at present. (In any case, the single-header version is similar to what you'll get when you #include <algorithm> in C++20).

If you use Conan you can find the latest testing package at bintray or just use the nanorange/20191001 package in conan-center.

Finally, if you use vcpkg, you can install the latest version of NanoRange from master using

vcpkg install nanorange --head

Compatibility

NanoRange requires a conforming C++17 compiler, and is tested with GCC 7 and Clang 4.0 and newer. Older versions may work in some cases, but this is not guaranteed.

In addition, NanoRange works with MSVC 2017 version 15.9. Note that the /permissive- switch is required for correct two-phase lookup.

Documentation

There is currently no reference documentation for NanoRange itself, but the Ranges TS on which it is based is partially documented on cppreference.

What it provides

Concepts

NanoRange provides all of the concepts from the ranges papers in the form of constexpr bool variable templates. You can use these to constrain your own templates via std::enable_if, or in if constexpr statements in C++17. For example

template <typename Rng>
void foo(Rng&& rng) {
    if constexpr (nano::RandomAccessRange<Rng>) {
         // do something
    } else if constexpr (nano::BidirectionalRange<Rng>>) {
        // do something else
    } else if constexpr (nano::ForwardRange<Rng>) {
        // do a third thing
    }
}

Iterator adaptors

The One Ranges proposal P0896 adds two new iterator adaptors to the standard library, namely common_iterator and counted_iterator, which are both implemented in NanoRange.

Additionally, P0896 modifies the existing iterator adaptors for compatibility with the new concepts. NanoRange therefore provides drop-in replacements for these, specifically:

  • reverse_iterator
  • front_insert_iterator
  • back_insert_iterator
  • insert_iterator
  • istream_iterator
  • ostream_iterator
  • istreambuf_iterator
  • ostreambuf_iterator

Lastly, NanoRange provides an implementation of subrange from P0896. This can be used to turn an iterator/sentinel pair into in range, or as a span-like view of a subset of another range.

Algorithms

Range-based overloads

NanoRange provides range-based overloads of all the algorithms in <algorithm>. This means that you can finally say

std::vector<int> vec{5, 4, 3, 2, 1};
nano::sort(vec);

and it will Just Work.

Constraint checking

In the existing STL, the algorithm calls are unconstrained. This means that if you pass an argument which doesn't meet the requirements of the function, the compiler will go ahead and try to instantiate the template anyway, usually resulting in pages of error messages with template backtraces for which C++ is infamous.

For example, the following program has an error: a std::list iterator is not random-access, and so doesn't meet the requirements of std::sort():

int main()
{
    std::list<int> list{5, 4, 3, 2, 1};
    std::sort(list.begin(), list.end());
}

Compiling this two-line example with Clang 6.0 results in over 350 lines of error messages!

Calling nano::sort() instead of std::sort() on the other hand means that constraints are checked before the template is instantated. This time, the entire error output is:

example.cpp:9:5: error: no matching function for call to object of type 'const nano::ranges::detail::sort_fn'
    nano::sort(list.begin(), list.end());
    ^~~~~~~~~~
include/nanorange/algorithm/stl/sort.hpp:26:5: note: candidate template ignored: requirement 'RandomAccessIterator<std::__1::__list_iterator<int, void *> >' was not satisfied [with I = std::__1::__list_iterator<int, void *>, Comp = nano::ranges::less<void>]
    operator()(I first, I last, Comp comp = Comp{}) const
    ^
include/nanorange/algorithm/stl/sort.hpp:37:5: note: candidate template ignored: substitution failure [with Rng = std::__1::__list_iterator<int, void *>, Comp = std::__1::__list_iterator<int, void *>]: no matching function for call to object of type 'const nano::ranges::detail::begin_::fn'
    operator()(Rng&& rng, Comp comp = Comp{}) const
    ^
1 error generated.

which makes it clear that the first overload was rejected because list::iterator doesn't meet the requirements of RandomAccessIterator, and the second overload was rejected because list::iterator is not a range (you can't call nano::begin() on it). Much better.

Function objects

The algorithms in NanoRange are implemented as non-template function objects with templated function call operators. This means that you can pass them around without needing to specify template arguments or wrap them in lambdas. For example:

std::vector<std::vector<int>> vec_of_vecs = ...

nano::for_each(vec_of_vecs, nano::sort); // sorts each inner vector

Projections

The fully reimplemented algorithms (see below) offer support for projections. A projection is a unary callable which modifies ("projects") the view of the data that the algorithm sees. Because projections are routed through (an implementation of) std::invoke(), it's possible to use pointers to member functions and pointers to member data as projections. For example:

struct S {
    int i;
    float f;
};

std::vector<S> vec = ...

auto iter = nano::find(vec, 10, &S::i);
// iter points to the first member of vec for which i == 10

constexpr support

In P0896, almost all the algorithms are marked as constexpr (the exceptions being those which can potentially allocate temporary storage). NanoRange fully supports this, meaning the vast majority of algorithms can be called at compile-time. For example

auto sort_copy = [](auto rng) {
    nano::sort(rng);
    return rng;
};

int main()
{
    constexpr std::array a{5, 4, 3, 2, 1};
    constexpr auto b = sort_copy(a);

    static_assert(nano::is_sorted(b));
}

Ranges papers

The Ranges proposals have been consolidated into two main papers:

NanoRange fully implements the first, and implements most of the second (except for Views).

Stability

NanoRange aims to track the various C++20 ranges proposals, and will be updated as new papers are published. As such, there are no API stability guarantees at this time.

Licence

NanoRange is provided under the Boost licence. See LICENSE_1_0.txt for details.

Acknowledgements

Many thanks to the following:

  • Eric Niebler and Casey Carter for the Ranges TS, Range-V3 and CMCSTL2. You guys are awesome.

  • Orson Peters for pdqsort

  • Phil Nash for the fantastic Catch testing framework

  • The editors of cppreference.com for painstakingly detailing the existing requirements of standard library algorithms, and more generally for maintaining the C++ programmer's bible.

nanorange's People

Contributors

caseycarter avatar denisyaroshevskiy avatar dvirtz avatar franckrj avatar nyarlathotep-prog avatar paulbendixen avatar siebenschlaefer avatar tcbrindle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nanorange's Issues

"Conversion from difference_type to int loses data" in partial_insertion_sort

template <typename I, typename Comp, typename Proj>
constexpr bool partial_insertion_sort(I begin, I end, Comp& comp, Proj& proj)
{
    using T = value_type_t<I>;

    if (begin == end) {
        return true;
    }

    int limit = 0; // ------- NOTE : declaration here ---------
    for (I cur = begin + 1; cur != end; ++cur) {
        if (limit > pqdsort_partial_insertion_sort_limit) {
            return false;
        }

        I sift = cur;
        I sift_1 = cur - 1;

        // Compare first so we can avoid 2 moves for an element already
        // positioned correctly.
        if (nano::invoke(comp, nano::invoke(proj, *sift),
                         nano::invoke(proj, *sift_1))) {
            T tmp = nano::iter_move(sift);

            do {
                *sift-- = nano::iter_move(sift_1);
            } while (sift != begin &&
                     nano::invoke(comp, nano::invoke(proj, tmp),
                                  nano::invoke(proj, *--sift_1)));

            *sift = std::move(tmp);
            limit += cur - sift;
        }
    }

    return true;
}

limit should probably be a difference_type_t<I>

Use a union to store common_iterator's members

The current implementation of common_iterator stores both the iterator and sentinel as direct members. Since only one of the members can be active at any time, this always wastes space.

P0896 has a note that common_iterator's members should be respecified in terms of std::variant. While we can't use variant (as it's C++17 only), we should use a simple tagged union to avoid making common_iterator twice as big as it needs to be.

Fix copy'n'paste error in front_insert_iterator

cont_->front_back(std::move(value));

This looks like a copy & paste error where back_insert_iterator.hpp was copied and push_back() was mistakenly changed to front_back instead of push_front like in line 27:

Disclaimer: I just started toying with NanoRange, so the code may be totally fine. In that case just close this issue, sorry. Also, I didn't find any tests for the insert iterators, so I couldn't add a test case.

NanoRange failed with error C2903, C2760, C2187 when build with MSVC

Hi All,
I tried to build NanoRange with VS2017 Update 7 on Windows. It failed to build due to the error C2903, C2760, C2187. This issue can be reproduced from master revision 07be3bf. Could you please help take a look at this? Thanks!

Expected behavior:
build successfully

Actual behavior:
The whole log file please see attachment.
NanoRange_x86_build.log
d:\nanorange\src\include\nanorange\detail\common_reference.hpp(144,59): error C2903: using type = std::add_cv_t<typename xref::template type>; [D:\NanoRange\build_x86\test\test_nanorange.vcxproj]
d:\nanorange\src\include\nanorange\detail\common_reference.hpp(144,59): error C2903: ^ [D:\NanoRange\build_x86\test\test_nanorange.vcxproj]
d:\nanorange\src\include\nanorange\detail\common_reference.hpp(144,41): error C2760: syntax error: unexpected token '::', expected 'id-expression' [D:\NanoRange\build_x86\test\test_nanorange.vcxproj]
d:\nanorange\src\include\nanorange\detail\common_reference.hpp(144,41): error C2760: using type = std::add_cv_t<typename xref::template type>; [D:\NanoRange\build_x86\test\test_nanorange.vcxproj]
d:\nanorange\src\include\nanorange\detail\common_reference.hpp(144,41): error C2760: ^ [D:\NanoRange\build_x86\test\test_nanorange.vcxproj]
d:\nanorange\src\include\nanorange\detail\common_reference.hpp(144,64): error C2187: syntax error: 'identifier' was unexpected here [D:\NanoRange\build_x86\test\test_nanorange.vcxproj]
d:\nanorange\src\include\nanorange\detail\common_reference.hpp(144,64): error C2187: using type = std::add_cv_t<typename xref::template type>; [D:\NanoRange\build_x86\test\test_nanorange.vcxproj]
d:\nanorange\src\include\nanorange\detail\common_reference.hpp(144,64): error C2187: ^ [D:\NanoRange\build_x86\test\test_nanorange.vcxproj]

Steps to reproduce the behavior:

  1. Open VS2017 x86 Native tools command tool
  2. git clone https://github.com/tcbrindle/nanorange d:\NanoRange\src
  3. cd D:\NanoRange
  4. mkdir build_x86 && pushd build_x86
  5. cmake -G "Visual Studio 15 2017" -DCMAKE_SYSTEM_VERSION=10.0.17134.0 -DCMAKE_CXX_STANDARD=17 ..\src\
  6. msbuild /m /p:Configuration=Release;Platform=Win32 nanorange.sln /t:Rebuild

Thanks,
Shanshan

Support for the Concepts TS

Do you plan to support C++20 concepts and possibly also the Concepts TS? I guess redefining NANO_CONCEPT as concept / concept bool is not sufficient as you need to make sure the subsumption rules work, as well...

Thanks!

Benchmarks. Implement initial benchmark support and write one for rotate.

Hi, Tristan.

I sketched out the initial ground for working on rotate, don't know how much effort I will put in, but I believe it's useful as is at this stage.

Building for benchmarks is hard:

  • first of you need a benchmarking library as a dependency. I tried a few and the only one that really works for me is google benchmark. I just have it installed locally, maybe some of package managers could help, but this is the area where I know absolutely nothing. Same goes for build systems - I just use a script.
  • Ideally you want a binary per benchmark that you run: there is an issue of code alignment - code that doesn't run can affect the performance of your benchmark. (Example of an issue like that: google/benchmark#461). For now I just wrote a script that compiles one binary with clang - see for yourself if you want anything smarter than that.

NOTE: libc++ and some other projects compile multiple benchmarks in one binary. As far as I understand - performance is not the top priority for you so maybe it's OK. Consider that maybe all together attempt to benchmark is too much of a hassle for your project, if you just want the proof of concept.

Initial benchmarking results:

The sad part of this whole experiment so far is that you beat libc++ every-time they don't have a special case. I don't know if this is due to gcd rotate being bad all together or just libc++ one's being bad or even me messing up the benchmarks (though I doubt it) but seems it's like that.

Here are my measurements: (note - grain of salt - I ran them little less careful then I probably should have - didn't turn off other programs and the laptop was off power, but the results are pretty consistent).

Special cases are: 1 element and middle.

--------------------------------------------------------------------------------------------
Benchmark                                                     Time           CPU Iterations
--------------------------------------------------------------------------------------------
rotate_random_access<nano_rotate, int>/1/999               1720 ns       1718 ns     405901
rotate_random_access<nano_rotate, int>/100/900              743 ns        742 ns     929257
rotate_random_access<nano_rotate, int>/400/600              785 ns        784 ns     886031
rotate_random_access<nano_rotate, int>/500/500              419 ns        418 ns    1682919
rotate_random_access<nano_rotate, int>/700/300             1104 ns       1102 ns     631495
rotate_random_access<nano_rotate, int>/999/1               1404 ns       1402 ns     495523
rotate_random_access<nano_rotate, int>/700000/350000     822820 ns     820340 ns        814
rotate_random_access<nano_rotate, int>/30000/16127        55079 ns      54948 ns      12591

-------------------------------------------------------------------------------------------
Benchmark                                                    Time           CPU Iterations
-------------------------------------------------------------------------------------------
rotate_random_access<std_rotate, int>/1/999                 51 ns         51 ns   13643097
rotate_random_access<std_rotate, int>/100/900             1269 ns       1258 ns     535598
rotate_random_access<std_rotate, int>/400/600             1096 ns       1094 ns     573047
rotate_random_access<std_rotate, int>/500/500               93 ns         93 ns    7549367
rotate_random_access<std_rotate, int>/700/300             1237 ns       1234 ns     565191
rotate_random_access<std_rotate, int>/999/1                 52 ns         52 ns   13220518
rotate_random_access<std_rotate, int>/700000/350000    1072748 ns    1068835 ns        653
rotate_random_access<std_rotate, int>/30000/16127       104161 ns     103922 ns       6702

Fully implement the remaining algorithms

A small number of algorithms are still implemented as wrappers around the existing standard library versions. These are:

  • nth_element
  • stable_sort
  • stable_partition
  • inplace_merge

The last three are particularly tricky as they require the use temporary storage, falling back to a slower algorithm if extra memory is not available.

Nanorange failed with error C2607 on MSVC

Hi all,

NanoRange assert failed on upcoming version of MSVC: F:\gitP\tcbrindle\nanorange\test\test_concepts.cpp(183): error C2607: static assertion failed

The failing line is:

static_assert(rng::default_initializable);

which eventually reaches:

template
inline constexpr bool
is_default_initializable<T, std::void_t<decltype(::new T)>> = true;

'::new const int' is not valid as you cannot default initialize a 'const int'.

Use memmove optimisations when appropriate

When using contiguous iterators with trivially copyable/movable value types, we should be able to optimise copy/move and their backwards versions to use std::memmove. This would have knock-on benefits for several other algorithms which end up copying or moving elements in their implementations.

Unfortunately memmove is not constexpr, so we'd need to use C++20 std::is_constant_evaluated to detect whether we're being called at compile-time (and should therefore just use the normal implementation) or at run-time. The preprocessor define __cpp_lib_is_constant_evaluated is supported in GCC and Clang to find out whether is_constant_evaluated is available, but I'm not sure about MSVC.

A couple of comments

Hey @tcbrindle! Nice work on the library. Some thoughts I had while wandering:

  • in README.md:

    NanoRange is also missing the tagged_tuple/tagged_pair machinery from P0896; instead, std::pair and std::tuple are used as return types from algorithms.

    Don't bother: LEWG decided that they hate tagged, and requested that we replace all of the tagged return types with new named class types with named members.

  • also in README.md:

    Having said that, a couple of NanoRange selling points might be ... It's very much smaller.

    Have you done any comparative compile-time benchmarking?

  • in include/nanorange/detail/concepts/core.hpp:

    // FIXME: Spec doesn't use remove_reference_t here, not sure if it should
    template <typename Derived, typename Base>
    NANO_CONCEPT DerivedFrom = std::is_base_of<Base, Derived>::value&&
       std::is_convertible<const volatile std::remove_reference_t<Derived>*,
                           const volatile std::remove_reference_t<Base>*>::value;

    Only non-union class types (never reference types) can satisfy is_base_of.

Support better CMake install for to use with modern CMake.

I just tried this library. It fits my purpose over range-v3 because Eric refuses to support the Intel compiler and I need to support it.
I decided to install it using conan.
The trouble, minor in the grand scheme of things, but nagging nonetheless, is that one cannot simply use:

find_package(nanorange REQUIRED)
target_link_libraries(executable nanorange)

Instead I had to use

include_directories(${nanorange_INCLUDE_DIRS})

This approach, though it works for my immediate purpose, is not appropriate for libraries that will be used by other targets in other projects.

I have not fully mastered the latest version of conan, but I have made some install scripts that rely on CMake install configurations that also installs the config version of '.cmake' files. When that is done properly then using

find_package(nanorange REQUIRED NO_MODULES)
target_link_libraries(executable nanorange)

with or without conan will do the job.
One good thing is that the conan python file of nanorange relies on the cmake install, so the only modifications required should be in the install configuration inside of CMakeLists.txt
If I can help, I think it shouldn't take me too long to create a PR for this, based on some of my own libraries.

Typos in insert_iterator?

Spotted a few things when trying to use range algorithms with a std::map. I'm guessing they're just copy/paste errors from being based off back_insert_iterator? ;)

This should be using insert and not push_back:

insert_iterator& operator=(iter_value_t<Container>&& value)
{
cont_->push_back(it_, std::move(value));
++it_;
return *this;
}

Missing the iterator argument and constructing the wrong type:

insert_iterator<Container> inserter(Container& x)
{
return back_insert_iterator<Container>(x);
}

nano::equal complains about comparing two ranges

I get some very strange behaviour when trying to use nano::equal, as shown below. array_expression is EqualityComparable, and this example works when I use both range-v3 and cmcstl2.

void check_invariants(gsl::span<std::pair<array_expression, std::string_view>> const expressions,
   std::array<std::string_view, 3> const& names)
{
   Expects(nano::distance(expressions) == nano::distance(names));
   check_basic_invariants(expressions);
   CHECK(nano::equal(expressions, names, std::equal_to<>{}, &std::pair<array_expression, std::string_view>::second));
}

Offending expression: nano::equal(expressions, names, std::equal_to<>{}, &std::pair<array_expression, std::string_view>::second).

Diagnostic:
error.txt

split view does not work

Hi, it seems that nano::split_view does not work as expected for a simple case (at least on gcc 8-9-trunk):

int main()
{   
  std::string words = "hello;world";
  std::string delimiter = ";";
  auto foo = words | rng::views::split(delimiter);
}

Godbolt link

rotate() could be faster

From #37, it seems that NanoRange's implementation of rotate() is generally faster than libc++ (with a couple of exceptions which they have special-cased) but very much slower than libstdc++.

Unfortunately the GPL'd code of libstdc++ means we can't just go and "borrow" their implementation, but there is clearly room for improvement.

Need a better explanation of the difference from ranges-v3

The repository's README says it is intended for people who "don't want to (or can't) use the full-blown Range-V3". This is a vague statement. difficult to understand. I mean, other than the fact that Nano is missing some Ranges-V3 features - what's the difference? Why would someone want to use the same functionality from Nano rather than from Ranges-V3? The explanation should be more detailed and explicit.

Is there a plan to support more of the views/things in range-v3 that weren't standardized?

Right now I'm really eyeing up zip/zip_with as a means to kill off classical for loops when you need an index. It's one of the many things that are in range-v3 but neither here nor the standard. There's still a niche where projects cannot use range-v3 but can use this library, and initially trying to port over some useful stuff from range-v3 has proven to be a bit of a rabbit hole due to all the metaprogramming library constructs, leading me to maybe just do it from scratch.

Or maybe even a companion library if we want to keep the scope to what's in the standard?

NanoRange failed to build due to errors C2677 C3536 C2893 C2062 C2607 C2672 C2676 with MSVC on windows

Environment:
Windows Server 2016 + VS2017 + NanoRange master branch latest srouce code.

NanoRange failed to build due to errors C2677 C3536 C2893 C2062 C2607 C2672 C2676 with MSVC on windows. It can be reproduced on master revision 391cc95 . Could you help have a look about this issue? Thanks in advance!

Steps to reproduce the behavior:
1.Open VS2017 x86 Native tools command tool
2.git clone https://github.com/tcbrindle/nanorange d:\NanoRange\src
3.cd D:\NanoRange
4.mkdir build_x86 && pushd build_x86
5.cmake -G "Visual Studio 15 2017" -DCMAKE_SYSTEM_VERSION=10.0.17134.0 -DCMAKE_CXX_STANDARD=17 ..\src
6.msbuild /m /p:Configuration=Release;Platform=Win32 nanorange.sln /t:Rebuild

log_x86_build.log

Actual result:
D:\NanoRange\src\test\view\filter_view.cpp(45): error C2677: binary '|': no global operator found which takes type
D:\NanoRange\src\test\view\filter_view.cpp(48): error C3536: 'rng': cannot be used before it is initialized [D:\NanoRange\build_x86\test\test_nanorange.vcxproj]
D:\NanoRange\src\test\view\filter_view.cpp(48): error C2893: Failed to specialize function template 'unknown-type nano::ranges::detail::begin_::fn::operator ()(T &&) noexcept() const' [D:\NanoRange\build_x86\test\test_nanorange.vcxproj]
D:\NanoRange\src\test\view\filter_view.cpp(48): error C2062: type 'unknown-type' unexpected [D:\NanoRange\build_x86\test\test_nanorange.vcxproj]
D:\NanoRange\src\test\view\filter_view.cpp(49): error C2607: static assertion failed [D:\NanoRange\build_x86\test\test_nanorange.vcxproj]
D:\NanoRange\src\test\view\filter_view.cpp(141): error C2672: 'operator __surrogate_func': no matching overloaded function found [D:\NanoRange\build_x86\test\test_nanorange.vcxproj]
D:\NanoRange\src\test\view\filter_view.cpp(135): error C2676: binary '|': 'nano::ranges::iota_view<_Ty,nano::ranges::unreachable_sentinel_t>' does not define this operator or a conversion to a type acceptable to the predefined operator [D:\NanoRange\build_x86\test\test_nanorange.vcxproj]

nano::to_vector ?

Sorry if it is obvious, but I did not find a way to convert a range to a vector.
Simple example:
std::vector<int> = nano::views::iota(0, 1000); // | nano::to_vector ?

//In Range-v3
return ranges::views::iota(0, starterSize) | ranges::to_vector;

So, is it possible? Thanks

viewable_range and iota_view not to spec

static_assert(nano::ranges::viewable_range<nano::ranges::iota_view<int>>); // okay
static_assert(std::ranges::viewable_range<ranges::iota_view<int>>); // error

Update to C++20

Now that C++20 has been finalised, NanoRange should aim to match the spec as closely as possible.

Current task list:

  • Remove forwarding_range, add borrowed_range (PR #86)
  • Remove boolean, add boolean_testable (PR #89)
  • default_constructible -> default_initializable (PR #89)
  • Support move-only views
  • Remove converting constructors from various views (yay!) (PR #99)
  • Add ssize() (PR #92)
  • Update algorithm result types (again)
  • Add the algorithms that weren't in P0896 (sample, for_each_n, clamp) (PR #96)
  • Liberally sprinkle [[nodiscard]] around the place

common_reference broken with MSVC 19.22

The latest MSVC update (v19.22) breaks our implementation of common_reference, to the extent that just #include <nanorange.hpp> generates

error C2064: term does not evaluate to a function taking 0 arguments
note: see reference to alias template instantiation 'nano::ranges::detail::cond_res_t<copy_cv<X,Y>::type&,copy_cv<Y,X>::type&>' being compiled

(See https://godbolt.org/z/VXv5gY)

The offending line seems to be https://github.com/tcbrindle/NanoRange/blob/master/include/nanorange/detail/common_reference.hpp#L68. I'm not sure of the cause -- this should be in a SFINAE context, so if evaluation of the alias causes a substitution failure, then the partial specialisation should just be ignored... or at least that's the idea.

It works correctly with Clang, GCC and previous versions of MSVC, so it may just be a compiler bug, or it may be that MSVC is now correctly diagnosing a problem that we previously got away with. Either way, this prevents NanoRange being used with the latest Windows compiler, so it needs to be fixed ASAP.

typo in test\algorithm\mismatch.cpp

Hi,
I'm a developer from Visual C++ compiler team.
As you may know, we added NanoRange to our daily RWC (real world code) testing.
We saw a test failure and it appears to be source issue.

	std::pair<S const *, S const *> ps2
		= ranges::mismatch(ranges::begin(s1), ranges::end(s2), s2, std::equal_to<int>(), &S::i, &S::i);

Based on the declaration of 'mismatch', 'ranges::end(s2)' is likely a typo of 'ranges::end(s1)'.
The test passes after I change 's2' to 's1'.

Add istream_range

P1035 proposes a std::istream_range class. This is useful for converting input streams into ranges without needing to default-construct an istream_iterator to act as a sentinel.

The proposal paper suggests that istream_range should useistream_iterator as its iterator type. Arguably a better design choice would be to store the istream pointer and cached next value directly in the range object itself, as Range-V3 does in its istream_range implementation. This would allow istream_range::iterator to simply hold a pointer to the parent range, making these iterators much cheaper to copy.

implement view::concat?

I don't think it's in the ranges TS, but it's in ranges-v3, and I have an implementation if you'd like it.

(Note: concat is a terribly unintuitive name, if at all possible I would rename it to chain - this is what it's called in both Rust and D)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.