C++ Ranges

本文分享了一些C++ Ranges
展开查看详情

1. The One Ranges Proposal Three Proposals for Views under the Sky, Seven for LEWG in their halls of stone, Nine for the Ranges TS doomed to die, One for the LWG on its dark throne In the Land of Geneva where the Standard lie. One Proposal to ranges::merge them all, One Proposal to ranges::find them, One Proposal to bring them all and in namespace ranges bind them, In the Land of Geneva where the Standard lie.

2.C++ Ranges 吴咏炜 wuyongwei@gmail.com C++ Conference China 2018 · Shenzhen · PureCpp.org

3.A Bit of History Boost.Range, 2003 D range, ~2009 Range-v3, 2013 Range TS, 2014 Merged into C++20, 2018 Formally standardized, ~2020 !3

4.About the Code All code can be compiled with GCC with concept support (-fconcept) C++17 support (-std=c++17) Cmcstl2 (https://github.com/CaseyCarter/cmcstl2) Some need range-v3 (https://github.com/ericniebler/range-v3) Some need nvwa (https://github.com/adah1972/nvwa) Not in final C++20 form Code is available at: https://github.com/adah1972/cpp_conf_china_2018 !4

5.Pre-Ranges Code int a[] = {1, 7, 3, 6, 5, 2, 4, 8}; std ::sort(std ::begin(a), std ::end(a)); std ::copy(std ::begin(a), std ::end(a), std ::ostream_iterator<int>( std ::cout, " ")); !5

6.Ranges Example—Sort namespace ranges = std ::experimental ::ranges; int a[] = {1, 7, 3, 6, 5, 2, 4, 8}; ranges ::sort(a); ranges ::copy(a, ranges ::ostream_iterator<int>( std ::cout, " ")); !6

7.Ranges Example—Reverse View namespace ranges = std ::experimental ::ranges; int a[] = {1, 7, 3, 6, 5, 2, 4, 8}; auto r = ranges ::reverse_view(a); ranges ::copy(a, ranges ::ostream_iterator<int>( std ::cout, " ")); !7

8.Ranges Example—Filter View namespace ranges = std ::experimental ::ranges; int a[] = {1, 7, 3, 6, 5, 2, 4, 8}; auto r = ranges ::filter_view(a, [](int i) { return i % 2 == 0; }); ranges ::copy(a, ranges ::ostream_iterator<int>( std ::cout, " ")); !8

9.Ranges Example—Nested Views namespace ranges = std ::experimental ::ranges; int a[] = {1, 7, 3, 6, 5, 2, 4, 8}; auto r = ranges ::reverse_view( ranges ::filter_view(a, [](int i) { return i % 2 == 0; })); ranges ::copy(a, ranges ::ostream_iterator<int>( std ::cout, " ")); !9

10.Ranges Example—Pipe namespace ranges = std ::experimental ::ranges; int a[] = {1, 7, 3, 6, 5, 2, 4, 8}; auto r = a | ranges ::view ::filter( [](int i) { return i % 2 == 0; }) | ranges ::view ::reverse; ranges ::copy(a, ranges ::ostream_iterator<int>( std ::cout, " ")); !10

11.Thinking of Unix Pipe do_something … | grep … | sort | uniq !11

12.What is a range, exactly? !12

13.Definition of Range template<class T> concept bool _RangeImpl = requires(T && t) { ranges ::begin(static_cast<T &&>(t)); ranges ::end(static_cast<T &&>(t)); }; template<class T> concept bool Range = _RangeImpl<T&>; !13

14.Basic Concepts Regular Semiregular EqualityComparable Copyable DefaultConstructible CopyConstructible Movable Assignable MoveConstructible Swappable !14

15.Iterator-related Concepts ContiguousIterator RandomAccessIterator BidirectionalIterator StrictTotallyOrdered ForwardIterator EqualityComparable InputIterator OutputIterator Iterator Readable WeaklyIncrementable Writable Semiregular !15

16.Range Concepts ContiguousRange RandomAccessRange BidirectionalRange ForwardRange InputRange OutputRange SizedRange CommonRange View Range Semiregular Copyable DefaultConstructible !16

17.Definition of Range template<class T> concept bool _RangeImpl = requires(T && t) { ranges ::begin(static_cast<T &&>(t)); ranges ::end(static_cast<T &&>(t)); }; template<class T> concept bool Range = _RangeImpl<T&>; !17

18.View template <class T> concept bool View = Range<T> && Semiregular<T> && enable_view<remove_cvref_t<T >>; !18

19.CommonRange template <class T> concept bool CommonRange = Range<T> && Same<iterator_t<T>, sentinel_t<T >>; !19

20.SizedRange template <class T> concept bool SizedRange = Range<T> && !disable_sized_range<remove_cvref_t<T >> && requires(T& r) { size(r); }; !20

21.OutputRange template <class R, class T> concept bool OutputRange = Range<R> && OutputIterator<iterator_t<R>, T>; !21

22.InputRange template <class T> concept bool InputRange = Range<T> && InputIterator<iterator_t<T >>; !22

23.A Sentinel Example struct null_sentinel {}; template <Iterator I> bool operator ==(I i, null_sentinel) { return *i == 0; } //template <Iterator I> //operator ==(null_sentinel, I i), operator !=, …
 ranges ::for_each(argv[1], null_sentinel(), [](char ch) { std ::cout << ch; }); !23

24.Views Do not own elements (but shared ownership is OK) Take constant time to copy, move, or assign Most containers are Ranges, but not Views C++17 string_view satisfies View, but string does not Views are Semiregular, i.e. Copyable and DefaultConstructible !24

25.Range Concept Check I vector<int> const vector<int> Range ✓ ✓ View ✗ ✗ SizedRange ✓ ✓ CommonRange ✓ ✓ OutputRange ✓ ✗ InputRange ✓ ✓ ForwardRange ✓ ✓ BidirectionalRange ✓ ✓ RandomAccessRange ✓ ✓ ContiguousRange ✓ ✓ !25

26.Range Concept Check II list<int> const list<int> Range ✓ ✓ View ✗ ✗ SizedRange ✓ ✓ CommonRange ✓ ✓ OutputRange ✓ ✗ InputRange ✓ ✓ ForwardRange ✓ ✓ BidirectionalRange ✓ ✓ RandomAccessRange ✗ ✗ ContiguousRange ✗ ✗ !26

27.Range Concept Check III int [8] int const [8] Range ✓ ✓ View ✗ ✗ SizedRange ✓ ✓ CommonRange ✓ ✓ OutputRange ✓ ✗ InputRange ✓ ✓ ForwardRange ✓ ✓ BidirectionalRange ✓ ✓ RandomAccessRange ✓ ✓ ContiguousRange ✓ ✓ !27

28.Range Concept Check IV reverse_view<int [8]> reverse_view<int const [8]> Range ✓ ✓ View ✓ ✓ SizedRange ✓ ✓ CommonRange ✓ ✓ OutputRange ✓ ✗ InputRange ✓ ✓ ForwardRange ✓ ✓ BidirectionalRange ✓ ✓ RandomAccessRange ✓ ✓ ContiguousRange ✗ ✗ !28

29.Range Concept Check V filter_view<int [8]> filter_view<int const [8]> Range ✓ ✓ View ✓ ✓ SizedRange ✗ ✗ CommonRange ✓ ✓ OutputRange ✓ ✗ InputRange ✓ ✓ ForwardRange ✓ ✓ BidirectionalRange ✓ ✓ RandomAccessRange ✗ ✗ ContiguousRange ✗ ✗ !29