namespace cpp {}

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


kennen:include:ranges

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
kennen:include:ranges [2024-02-19 13:21] – [Quellen und Senken] rrichterkennen:include:ranges [2024-02-22 21:04] (aktuell) – [Beispiele] rrichter
Zeile 1: Zeile 1:
 ====== <ranges> ====== ====== <ranges> ======
 Bereiche sind Elementfolgen, auf die ''%%begin(r)%%'' und ''%%end(r)%%'' anwendbar sind. Bereiche sind Elementfolgen, auf die ''%%begin(r)%%'' und ''%%end(r)%%'' anwendbar sind.
 +Die Algorithmen der Standardbibliothek erlauben seit [[..:begriffe#C++20]] die Schreibweise ''std::ranges::sort(v)'' statt ''std::sort(begin(v), end(v))''.
 +Allerdings sind die einzelnen Algorithmen jeweils nacheinander auszuführen, also nicht koppelbar.
 +MIt einem anderen Ansatz soll dieser Nachteil behoben werden.
 +
 Im Namensraum ''std::ranges::views'' oder kurz ''std::views''  Im Namensraum ''std::ranges::views'' oder kurz ''std::views'' 
 definierte Sichten auf Bereiche lassen sich über Pipes ''|'' aneinander koppeln.  definierte Sichten auf Bereiche lassen sich über Pipes ''|'' aneinander koppeln. 
-Sie liefern die Werte eines Bereiches einzeln auf Anforderung.+Sie liefern die Werte eines Bereiches einzeln auf Anforderung, also über [[https://de.wikipedia.org/wiki/Lazy_Evaluation|lazy evaluation]].
  
 <code cpp views_pipelines.cpp> <code cpp views_pipelines.cpp>
Zeile 43: Zeile 47:
 </code> </code>
 ===== Quellen und Senken ===== ===== Quellen und Senken =====
-Sequentielle (und assoziative) Container können als Quellbereiche dienen. Mit ''ranges::to<Container>()'' (C++23) wird ein neuer Container als Senke für die verarbeiteten Daten erzeugt. Der Elementtyp wird automatisch bestimmt.+Sequentielle und assoziative (!) Container können als Quellbereiche dienen. Mit ''ranges::to<Container>()'' (C++23) wird ein neuer Container als Senke für die verarbeiteten Daten erzeugt. Der Elementtyp wird automatisch bestimmt.
  
 <code cpp to.cpp> <code cpp to.cpp>
Zeile 53: Zeile 57:
 int main() int main()
 { {
-    std::set<char> s{ 'h', 'a', 'l', 'o' };+    std::set s{ 'h', 'a', 'l', 'o' };
     auto v = s | std::views::take(2) | std::ranges::to<std::vector>();     auto v = s | std::views::take(2) | std::ranges::to<std::vector>();
     for (auto e : v) std::cout << e;      for (auto e : v) std::cout << e; 
Zeile 87: Zeile 91:
  
 ===== Sichten ===== ===== Sichten =====
-übernehmen einen Bereich, verarbeiten dessen Elemente ''e'' und geben sie weiter.+übernehmen einen oder mehrere Bereiche, verarbeiten dessen / deren Elemente ''e'' und geben sie weiter.
  
 | ''all'' | gibt alle Elemente weiter | ° | | ''all'' | gibt alle Elemente weiter | ° |
Zeile 122: Zeile 126:
  
 ===== Beispiele ===== ===== Beispiele =====
 +<file>
 +empty<T>                                 : []
 +single(42)                               : [42]
 +iota(0,6)                                : [0, 1, 2, 3, 4, 5]
 +iota(0) | take(3)                        : [0, 1, 2]
 +repeat(6) | take(3)                      : [6, 6, 6]
  
 +counted(begin(v),size(v))                : [1, 3, 5, 4, 2]
 +v | all                                  : [1, 3, 5, 4, 2]
 +v | drop_while(below_5)                  : [5, 4, 2]
 +v | enumerate                            : [(0, 1), (1, 3), (2, 5), (3, 4), (4, 2)]
 +v | filter(below_5)                      : [1, 3, 4, 2]
 +v | reverse                              : [2, 4, 5, 3, 1]
 +v | take_while(below_5)                  : [1, 3]
 +v | transform(square)                    : [1, 9, 25, 16, 4]
 +
 +v | chunk(3)                             : [[1, 3, 5], [4, 2]]
 +v | chunk_by(std::ranges::less{})        : [[1, 3, 5], [4], [2]]
 +v | pairwise_transform(double_digit)     : [13, 35, 54, 42]
 +v | pairwise                             : [(1, 3), (3, 5), (5, 4), (4, 2)]
 +v | slide(2)                             : [[1, 3], [3, 5], [5, 4], [4, 2]]
 +v | stride(2)                            : [1, 5, 2]
 +
 +s                                        : ['A', 'B', ' ', 'C', 'D', 'E']
 +s | split(' '                          : [['A', 'B'], ['C', 'D', 'E']]
 +s | split(' ') | join                    : ['A', 'B', 'C', 'D', 'E']
 +s | split(' ') | join_with("<>"s)        : ['A', 'B', '<', '>', 'C', 'D', 'E']
 +
 +zip(v, s)                                : [(1, 'A'), (3, 'B'), (5, ' '), (4, 'C'), (2, 'D')]
 +zip_transform(double_digit, v, v)        : [11, 33, 55, 44, 22]
 +cartesian_product(v|take(2), s|take(2))  : [(1, 'A'), (1, 'B'), (3, 'A'), (3, 'B')]
 +
 +m                                        : {"answer": 42, "wrong": 54}
 +m | keys                                 : ["answer", "wrong"]
 +m | values                               : [42, 54]
 +</file>
 +ist die Ausgabe des Programms
 <code cpp views_examples.cpp> <code cpp views_examples.cpp>
 #include <ranges> #include <ranges>
-#include <iostream> 
 #include <map> #include <map>
 #include <string> #include <string>
 #include <vector> #include <vector>
  
-// waiting for P2286 Formatting Ranges ...+// waiting for C++23 support: P2286 Formatting Ranges ... 
 +#if defined(__cpp_lib_format_ranges) && defined(__cpp_lib_print) 
 +#include <print> 
 + 
 +template <typename Range, typename Msg> 
 +void show(Range&& r, Msg message) 
 +
 +    std::print("{:<40}: {}", message, r); 
 +
 + 
 +template <typename Range, typename Msg> 
 +void show_range_of_ranges(Range&& r, Msg message) 
 +
 +    show(r, message);     
 +
 + 
 +template <typename Range, typename Msg> 
 +void show_range_of_pairs(Range&& r, Msg message) 
 +
 +    show(r, message);     
 +
 + 
 +template <typename Range, typename Msg> 
 +void show_map(Range&& r, Msg message) 
 +
 +    show(r, message);     
 +
 + 
 +#else 
 +#include <iostream> 
 + 
 +auto decorate(auto e)  
 +
 +    return e; 
 +
 + 
 +auto decorate(char e)  
 +
 +    return std::string("\'") + e + "\'"; 
 +
 + 
 +auto decorate(std::string e)  
 +
 +    return std::string("\"") + e + "\""; 
 +}
  
 template <typename Range, typename Msg> template <typename Range, typename Msg>
 void show(Range&& r, Msg message) void show(Range&& r, Msg message)
 { {
-    std::cout.width(30);+    std::cout.width(40);
     std::cout << std::left << message <<  " : [";     std::cout << std::left << message <<  " : [";
     int cnt = 0;         int cnt = 0;    
     for (auto&& e : r)      for (auto&& e : r) 
     {     {
-        std::cout << (cnt++ ? ",":"")+        std::cout << (cnt++ ? ", ":"") << decorate(e);
-        std::cout << e;    +
     }         }    
     std::cout << "]\n";     std::cout << "]\n";
Zeile 149: Zeile 231:
 void show_range_of_ranges(Range&& r, Msg message) void show_range_of_ranges(Range&& r, Msg message)
 { {
-    std::cout.width(30);+    std::cout.width(40);
     std::cout << std::left << message << " : [";     std::cout << std::left << message << " : [";
     int cnt = 0;         int cnt = 0;    
     for (auto&& inner_range : r)      for (auto&& inner_range : r) 
     {     {
-        std::cout << (cnt++ ? ",":"") << "[";+        std::cout << (cnt++ ? ", ":"") << "[";
         int inner_cnt = 0;             int inner_cnt = 0;    
         for (auto&& e : inner_range)          for (auto&& e : inner_range) 
         {         {
-            std::cout << (inner_cnt++ ? ",":""); +            std::cout << (inner_cnt++ ? ", ":"")  
-            std::cout << e;    +                      << decorate(e);
         }         }
         std::cout << "]";                 std::cout << "]";        
Zeile 165: Zeile 247:
     std::cout << "]\n";     std::cout << "]\n";
 } }
 +
 +template <typename Range, typename Msg>
 +void show_range_of_pairs(Range&& r, Msg message)
 +{
 +    std::cout.width(40);
 +    std::cout << std::left << message <<  " : [";
 +    int cnt = 0;    
 +    for (auto&& [a,b] : r) 
 +    {
 +        std::cout << (cnt++ ? ", ":""
 +                  << "(" << decorate(a) << ", " << decorate(b) << ")";    
 +    }    
 +    std::cout << "]\n";
 +}
 +
 +template <typename Range, typename Msg>
 +void show_map(Range&& r, Msg message)
 +{
 +    std::cout.width(40);
 +    std::cout << std::left << message <<  " : {";
 +    int cnt = 0;    
 +    for (auto&& [k,v] : r) 
 +    {
 +        std::cout << (cnt++ ? ", ":"")
 +                  << decorate(k) << ": " << decorate(v);    
 +    }    
 +    std::cout << "}\n";
 +}
 +
 +#endif // defined(__cpp_lib_format_ranges) && defined(__cpp_lib_print)
  
 int main() int main()
 { {
     using namespace std::views;     using namespace std::views;
 +    using namespace std::string_literals;
          
-    auto v = std::vector{0,1,2,3,4,5}; +    auto v = std::vector{ 1, 3, 5, 4, }; 
-    auto s = std::string{"AB CD E"};+    auto s = "AB CDE"s;
     auto m = std::map<std::string,int>{{"wrong", 6*9}, {"answer", 42}};     auto m = std::map<std::string,int>{{"wrong", 6*9}, {"answer", 42}};
 +    auto below_5 = [](int x){ return x < 5; };
 +    auto double_digit = [](int a, int b) { return 10*a + b; };
          
     show( empty<int>, "empty<T>");     show( empty<int>, "empty<T>");
Zeile 178: Zeile 293:
     show( iota(0,6), "iota(0,6)");     show( iota(0,6), "iota(0,6)");
     show( iota(0) | take(3), "iota(0) | take(3)");     show( iota(0) | take(3), "iota(0) | take(3)");
-    show( counted(begin(v), 3), "counted(begin(v),3)");+    show( repeat(6) | take(3), "repeat(6) | take(3)"); 
 +    std::cout << '\n'; 
 + 
 +    show( counted(begin(v), size(v)), "counted(begin(v),size(v))");
     show( v | all, "v | all");     show( v | all, "v | all");
 +    show( v | drop_while(below_5), "v | drop_while(below_5)");
 +    show_range_of_pairs(v | enumerate, "v | enumerate");
 +    show( v | filter(below_5), "v | filter(below_5)");
     show( v | reverse, "v | reverse");     show( v | reverse, "v | reverse");
-    show( v | take_while([](int x){ return x < 3; }), "v | take_while(below_3)"); +    show( v | take_while(below_5), "v | take_while(below_5)");
-    show( v | drop_while([](int x){ return x < 3; }), "v | drop_while(below_3)"); +
-    show( v | filter([](int x){ return x%2 != 0; }), "v | filter(odd)");+
     show( v | transform([](int x){ return x*x; }), "v | transform(square)");     show( v | transform([](int x){ return x*x; }), "v | transform(square)");
-    +    std::cout << '\n'; 
 + 
 +    show_range_of_ranges( v | chunk(3), "v | chunk(3)" ); 
 +    show_range_of_ranges( v | chunk_by(std::ranges::less{}), "v | chunk_by(std::ranges::less{})" ); 
 +    show( v | pairwise_transform(double_digit), "v | pairwise_transform(double_digit)" ); 
 +    show_range_of_pairs( v | pairwise, "v | pairwise" ); 
 +    show_range_of_ranges( v | slide(2), "v | slide(2)" ); 
 +    show( v | stride(2), "v | stride(2)" ); 
 +    std::cout << '\n'; 
     show( s , "s");     show( s , "s");
     show_range_of_ranges( s | split(' '), "s | split(\' \')");     show_range_of_ranges( s | split(' '), "s | split(\' \')");
     show( s | split(' ') | join, "s | split(\' \') | join");     show( s | split(' ') | join, "s | split(\' \') | join");
-    +    show( s | split(' ') | join_with("<>"s), "s | split(\' \') | join_with(\"<>\"s)"); 
 +    std::cout << '\n'; 
 + 
 +    show_range_of_pairs( zip(v, s), "zip(v, s)" ); 
 +    show( zip_transform(double_digit, v, v), "zip_transform(double_digit, v, v)" ); 
 +    show_range_of_pairs( cartesian_product(v|take(2), s|take(2)), "cartesian_product(v|take(2), s|take(2))" ); 
 +    std::cout << '\n'; 
 + 
 +    show_map( m , "m");
     show( m | keys , "m | keys");     show( m | keys , "m | keys");
     show( m | values , "m | values");     show( m | values , "m | values");
 } }
 </code> </code>
-erzeugt die Ausgabe +
-<file> +
-empty<T>                       : [] +
-single(42)                     : [42] +
-iota(0,6)                      : [0,1,2,3,4,5] +
-iota(0) | take(3)              : [0,1,2] +
-counted(begin(v),3)            : [0,1,2] +
-v | all                        : [0,1,2,3,4,5] +
-v | reverse                    : [5,4,3,2,1,0] +
-v | take_while(below_3)        : [0,1,2] +
-v | drop_while(below_3)        : [3,4,5] +
-v | filter(odd)                : [1,3,5] +
-v | transform(square)          : [0,1,4,9,16,25] +
-s                              : [A,B, ,C,D, ,E] +
-s | split(' '                : [[A,B],[C,D],[E]] +
-s | split(' ') | join          : [A,B,C,D,E] +
-m | keys                       : [answer,wrong] +
-m | values                     : [42,54] +
-</file>+
kennen/include/ranges.1708345303.txt.gz · Zuletzt geändert: 2024-02-19 13:21 von rrichter

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki