├── 1 - Modules ├── simple_math.cppm ├── simple_math.cpp ├── simple_math_template.cppm ├── simple_math_overloading.cppm ├── simple_math_overloading.cpp ├── example_simple.cpp ├── example_simple_module.cpp ├── example_simple_no_module.cpp ├── simple_main.cpp ├── simple_main_template.cpp └── simple_main_overloading.cpp ├── 3 - Concepts ├── too_specific1.cpp ├── can_add.cpp ├── too_generic.cpp ├── has_type_member.cpp ├── has_bool_value_member.cpp ├── too_specific2.cpp └── equal.cpp ├── .gitignore ├── 6 - Core & Library Features ├── jthread_join.cpp ├── thread_join.cpp ├── consteval.cpp ├── bit_cast.cpp ├── timezone1.cpp ├── timezone2.cpp ├── span.cpp ├── jthread_interrupt_argument.cpp ├── calendar.cpp ├── jthread_interrupt.cpp ├── spaceship_operator.cpp └── endian.cpp ├── .gitmodules ├── 5 - Format ├── named_arguments.cpp ├── type_safety.cpp ├── date.cpp ├── hello_world.cpp └── alignment.cpp ├── 2 - Ranges ├── range_comprehension1.cpp ├── lazy_evaluation.cpp ├── range_comprehension2.cpp └── function_composition.cpp ├── 4 - Coroutines ├── fibonacci.cpp ├── suspend_always.cpp ├── suspend_never.cpp └── generator.hpp ├── LICENSE └── README.md /1 - Modules/simple_math.cppm: -------------------------------------------------------------------------------- 1 | export module simple_math; 2 | 3 | export int add(int num1, int num2); -------------------------------------------------------------------------------- /1 - Modules/simple_math.cpp: -------------------------------------------------------------------------------- 1 | module simple_math; 2 | 3 | int add(int num1, int num2) 4 | { 5 | return num1 + num2; 6 | } -------------------------------------------------------------------------------- /1 - Modules/simple_math_template.cppm: -------------------------------------------------------------------------------- 1 | export module simple_math; 2 | 3 | export template 4 | T add(T a, T b) 5 | { 6 | return a + b; 7 | } -------------------------------------------------------------------------------- /1 - Modules/simple_math_overloading.cppm: -------------------------------------------------------------------------------- 1 | export module simple_math; 2 | 3 | export 4 | { 5 | int add(int num1, int num2); 6 | int add(int num1, int num2, int num3); 7 | } -------------------------------------------------------------------------------- /1 - Modules/simple_math_overloading.cpp: -------------------------------------------------------------------------------- 1 | module simple_math; 2 | 3 | int add(int num1, int num2) 4 | { 5 | return num1 + num2; 6 | } 7 | 8 | int add(int num1, int num2, int num3) 9 | { 10 | return num1 + num2 + num3; 11 | } -------------------------------------------------------------------------------- /1 - Modules/example_simple.cpp: -------------------------------------------------------------------------------- 1 | // Run with cl /experimental:module /EHsc /MD /std:c++latest example_simple.cpp 2 | 3 | import std.core; 4 | 5 | int main() 6 | { 7 | std::vector v{ "Plato", "Descartes", "Bacon" }; 8 | std::copy(v.begin(), v.end(), std::ostream_iterator(std::cout, "\n")); 9 | 10 | return 0; 11 | } -------------------------------------------------------------------------------- /3 - Concepts/too_specific1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void needInt(int i) 4 | { 5 | std::cout << "int: " << i << std::endl; 6 | } 7 | 8 | int main() 9 | { 10 | std::cout << std::endl; 11 | 12 | double d{1.234}; 13 | std::cout << "double: " << d << std::endl; 14 | 15 | needInt(d); 16 | 17 | std::cout << std::endl; 18 | } -------------------------------------------------------------------------------- /1 - Modules/example_simple_module.cpp: -------------------------------------------------------------------------------- 1 | // Run with cl /experimental:module /EHsc /MD /std:c++latest example_simple_module.cpp 2 | 3 | import std.core; 4 | 5 | int main() 6 | { 7 | std::vector v{ "Plato", "Descartes", "Bacon" }; 8 | std::copy(v.begin(), v.end(), std::ostream_iterator(std::cout, "\n")); 9 | 10 | return 0; 11 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /1 - Modules/example_simple_no_module.cpp: -------------------------------------------------------------------------------- 1 | // Run with cl example_simple_no_module.cpp /EHsc 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | std::vector v{ "Plato", "Descartes", "Bacon" }; 12 | std::copy(v.begin(), v.end(), std::ostream_iterator(std::cout, "\n")); 13 | 14 | return 0; 15 | } -------------------------------------------------------------------------------- /3 - Concepts/can_add.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl can_add.cpp /std:c++latest 4 | */ 5 | 6 | #include 7 | 8 | template 9 | concept can_add = requires(T t, U u) 10 | { 11 | t + u; 12 | }; 13 | 14 | template requires can_add 15 | auto add(T t, U u) 16 | { 17 | return t + u; 18 | } 19 | 20 | int main() 21 | { 22 | add(3, 4); 23 | //add("T", "U"); 24 | 25 | return 0; 26 | } -------------------------------------------------------------------------------- /3 - Concepts/too_generic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | T gcd(T a, T b) 5 | { 6 | if (b == 0) 7 | { 8 | return a; 9 | } 10 | else 11 | { 12 | return gcd(b, a % b); 13 | } 14 | } 15 | 16 | int main() 17 | { 18 | std::cout << std::endl; 19 | 20 | std::cout << gcd(100, 10) << std::endl; 21 | 22 | std::cout << gcd(3.5, 4.0) << std::endl; 23 | std::cout << gcd("100", "10") << std::endl; 24 | 25 | std::cout << std::endl; 26 | } -------------------------------------------------------------------------------- /6 - Core & Library Features/jthread_join.cpp: -------------------------------------------------------------------------------- 1 | // Run with in g++ 2 | /* 3 | g++ jthread_join.cpp -Wall -Wextra -std=gnu++2a 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | std::cout << std::endl; 12 | std::cout << std::boolalpha; 13 | 14 | std::jthread thr{[] { std::cout << "Joinable std::thread" << std::endl; }}; 15 | 16 | std::cout << "thr.joinable(): " << thr.joinable() << std::endl; 17 | 18 | std::cout << std::endl; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /6 - Core & Library Features/thread_join.cpp: -------------------------------------------------------------------------------- 1 | // Run with in g++ 2 | /* 3 | g++ thread_join.cpp -Wall -Wextra -std=gnu++2a 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | std::cout << std::endl; 12 | std::cout << std::boolalpha; 13 | 14 | std::thread thr{[] { std::cout << "Joinable std::thread" << std::endl; }}; 15 | 16 | std::cout << "thr.joinable(): " << thr.joinable() << std::endl; 17 | 18 | std::cout << std::endl; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /6 - Core & Library Features/consteval.cpp: -------------------------------------------------------------------------------- 1 | // Run with in g++ 2 | /* 3 | g++ consteval.cpp -Wall -Wextra -std=gnu++2a 4 | */ 5 | 6 | #include 7 | 8 | consteval int sqr(int n) 9 | { 10 | return n * n; 11 | } 12 | 13 | constexpr int r = sqr(100); // OK 14 | 15 | consteval int sqrsqr(int n) 16 | { 17 | return sqr(sqr(n)); // OK 18 | } 19 | 20 | // constexpr int dblsqr(int n) 21 | // { 22 | // return 2 * sqr(n); // Error 23 | // } 24 | 25 | int main() 26 | { 27 | std::cout << sqrsqr(10) << '\n'; 28 | 29 | return 0; 30 | } -------------------------------------------------------------------------------- /6 - Core & Library Features/bit_cast.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | constexpr double f64v = 19880124.0; 5 | constexpr auto u64v = std::bit_cast(f64v); 6 | constexpr std::uint64_t u64v2 = 0x3fe9000000000000ull; 7 | constexpr auto f64v2 = std::bit_cast(u64v2); 8 | 9 | int main() 10 | { 11 | std::cout << std::fixed << f64v << "f64.to_bits() == 0x" << std::hex << u64v 12 | << "u64\n"; 13 | std::cout << "f64::from_bits(0x" << std::hex << u64v2 14 | << "u64) == " << std::fixed << f64v2 << "f64\n"; 15 | 16 | return 0; 17 | } -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "2 - Ranges/range-v3"] 2 | path = 2 - Ranges/range-v3 3 | url = https://github.com/ericniebler/range-v3 4 | [submodule "4 - Coroutines/coro"] 5 | path = 4 - Coroutines/coro 6 | url = https://github.com/Quuxplusone/coro 7 | [submodule "4 - Coroutines/coroutine"] 8 | path = 4 - Coroutines/coroutine 9 | url = https://github.com/luncliff/coroutine 10 | [submodule "5 - Format/fmt"] 11 | path = 5 - Format/fmt 12 | url = https://github.com/fmtlib/fmt 13 | [submodule "6 - Core & Library Features/date"] 14 | path = 6 - Core & Library Features/date 15 | url = https://github.com/HowardHinnant/date 16 | -------------------------------------------------------------------------------- /5 - Format/named_arguments.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl.exe named_arguments.cpp /I fmt/include /std:c++latest /EHsc /MD /link fmt.lib 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | 10 | using namespace fmt::literals; 11 | 12 | int main() 13 | { 14 | // Named arguments 15 | fmt::print("Hello, {name}! The answer is {number}. Goodbye, {name}.\n", 16 | fmt::arg("name", "World"), fmt::arg("number", 42)); 17 | 18 | // C++11 user-defined literals (_a: alternative) 19 | fmt::print("Hello, {name}! The answer is {number}. Goodbye, {name}.\n", 20 | "name"_a = "World", "number"_a = 42); 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /3 - Concepts/has_type_member.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl has_type_member.cpp /std:c++latest 4 | */ 5 | 6 | #include 7 | 8 | template 9 | concept has_type_member = requires 10 | { 11 | typename T::type; 12 | }; 13 | 14 | struct S1 15 | { 16 | 17 | }; 18 | 19 | struct S2 20 | { 21 | using type = int; 22 | }; 23 | 24 | template 25 | constexpr bool has_type_member_f(T) 26 | { 27 | return has_type_member; 28 | } 29 | 30 | int main() 31 | { 32 | static_assert(!has_type_member); 33 | static_assert(has_type_member); 34 | 35 | static_assert(!has_type_member_f(S1{})); 36 | static_assert(has_type_member_f(S2{})); 37 | 38 | return 0; 39 | } -------------------------------------------------------------------------------- /6 - Core & Library Features/timezone1.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl.exe timezone1.cpp /I date/include /std:c++latest /EHsc 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace date; 13 | 14 | int main() 15 | { 16 | auto time = 17 | floor(std::chrono::system_clock::now()); 18 | std::cout << std::left << std::setw(25) << std::setfill(' ') << "Time" 19 | << time << std::endl; 20 | auto localtime = 21 | zoned_time(date::current_zone(), time); 22 | std::cout << std::left << std::setw(25) << std::setfill(' ') << "Local" 23 | << localtime << std::endl; 24 | 25 | return 0; 26 | } -------------------------------------------------------------------------------- /5 - Format/type_safety.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl.exe type_safety.cpp /I fmt/include /std:c++latest /EHsc /MD /link fmt.lib 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | 10 | int main() 11 | { 12 | // Part 1 13 | // Throw format_error exception: "unknown format code 'd' for string". 14 | fmt::format("The answer is {:d}\n", "forty-two"); 15 | 16 | // Report a compile-time error for the same reason 17 | //fmt::format(FMT_STRING("The answer is {:d}\n"), "forty-two"); 18 | 19 | // Part 2 20 | // Report a compile-time error because wide character L'\x42e' cannot be formatted into a narrow string 21 | fmt::format("Cyrillic letter {}\n", L'\x42e'); 22 | 23 | // fmt::format(L"Cyrillic letter {}\n", L'\x42e'); 24 | 25 | return 0; 26 | } -------------------------------------------------------------------------------- /2 - Ranges/range_comprehension1.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl.exe range_comprehension1.cpp /I ../../range-v3/include /std:c++latest /permissive- /experimental:preprocessor 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | 10 | using namespace ranges; 11 | 12 | int main() 13 | { 14 | std::cout << std::endl; 15 | 16 | // odds = [ x*x | x <-[1..] , odd x ] 17 | // takeWhile (<1000) odds -- [1, 9, 25, ... , 841, 961] 18 | 19 | auto odds = view::ints(1) | view::for_each([](int i) { 20 | return yield_if(i % 2 == 1, i * i); 21 | }); 22 | 23 | ranges::for_each(odds | view::take_while([](int i) { return i < 1000; }), 24 | [](int i) { std::cout << i << " "; }); 25 | 26 | std::cout << "\n\n"; 27 | 28 | return 0; 29 | } -------------------------------------------------------------------------------- /5 - Format/date.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl.exe date.cpp /I fmt/include /std:c++latest /EHsc /MD /link fmt.lib 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | 10 | struct date 11 | { 12 | int year, month, day; 13 | }; 14 | 15 | template <> 16 | struct fmt::formatter 17 | { 18 | constexpr auto parse(format_parse_context& ctx) 19 | { 20 | return ctx.begin(); 21 | } 22 | 23 | template 24 | auto format(const date& d, FormatContext& ctx) 25 | { 26 | return format_to(ctx.out(), "{}-{}-{}", d.year, d.month, d.day); 27 | } 28 | }; 29 | 30 | int main() 31 | { 32 | std::string s = fmt::format("The date is {}", date{2012, 12, 9}); 33 | 34 | // Python-like format string syntax using fmt 35 | fmt::print("{}\n", s); 36 | 37 | return 0; 38 | } -------------------------------------------------------------------------------- /6 - Core & Library Features/timezone2.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl.exe timezone2.cpp /I date/include /std:c++latest /EHsc 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace date; 13 | 14 | int main() 15 | { 16 | auto zone_names = { 17 | "Asia/Tokyo", "Asia/Hong_Kong", "Europe/Bucharest", 18 | "Europe/Berlin", "Europe/London", "America/New_York", 19 | "Pacific/Honolulu", 20 | }; 21 | 22 | auto now = floor(std::chrono::system_clock::now()); 23 | for (const auto& name : zone_names) 24 | { 25 | std::cout << std::left << std::setw(25) << std::setfill(' ') << name 26 | << zoned_time(name, now) 27 | << std::endl; 28 | } 29 | 30 | return 0; 31 | } -------------------------------------------------------------------------------- /2 - Ranges/lazy_evaluation.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl.exe lazy_evaluation.cpp /I ../../range-v3/include /std:c++latest /permissive- /experimental:preprocessor 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | using namespace ranges; 12 | 13 | int main() 14 | { 15 | std::cout << std::endl; 16 | 17 | // take 5 [1..] -- [1, 2, 3, 4, 5] 18 | 19 | auto num = view::take(view::ints(1), 5); 20 | ranges::for_each(num, [](int i) { std::cout << i << " "; }); 21 | 22 | std::cout << "\n\n"; 23 | 24 | auto pairs = 25 | view::zip_with([](int i, char c) { return std::make_pair(i, c); }, 26 | view::ints(0), "ranges"); 27 | 28 | ranges::for_each(pairs, [](std::pair p) { 29 | std::cout << "(" << p.first << ":" << p.second << ")"; 30 | }); 31 | 32 | std::cout << "\n\n"; 33 | 34 | return 0; 35 | } -------------------------------------------------------------------------------- /3 - Concepts/has_bool_value_member.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl has_bool_value_member.cpp /std:c++latest 4 | */ 5 | 6 | #include 7 | 8 | template 9 | concept has_bool_value_member = requires 10 | { 11 | { T::value } -> std::convertible_to; 12 | }; 13 | 14 | struct S1 15 | { 16 | 17 | }; 18 | 19 | struct S2 20 | { 21 | constexpr static bool value = true; 22 | }; 23 | 24 | struct S3 25 | { 26 | constexpr static S1 value{}; 27 | }; 28 | 29 | template 30 | bool get_value() 31 | { 32 | return T::value; 33 | } 34 | 35 | int main() 36 | { 37 | static_assert(!has_bool_value_member); 38 | static_assert(has_bool_value_member); 39 | static_assert(!has_bool_value_member); 40 | 41 | S1 s1; 42 | S2 s2; 43 | S3 s3; 44 | 45 | //get_value(); 46 | get_value(); 47 | //get_value(); 48 | 49 | return 0; 50 | } -------------------------------------------------------------------------------- /6 - Core & Library Features/span.cpp: -------------------------------------------------------------------------------- 1 | // Run with in g++ 2 | /* 3 | g++ span.cpp -Wall -Wextra -std=gnu++2a 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | template 13 | void func(std::span arr) 14 | { 15 | for (auto&& s : arr) 16 | { 17 | s[0] = std::toupper(s[0]); 18 | } 19 | } 20 | 21 | int main() 22 | { 23 | std::vector greeting = { "hello", "world" }; 24 | func(greeting); 25 | 26 | for (const auto& word : greeting) 27 | { 28 | std::cout << word << ' '; 29 | } 30 | std::cout << '\n'; 31 | 32 | std::array name = { "tom", "john" }; 33 | func(name); 34 | 35 | for (const auto& word : name) 36 | { 37 | std::cout << word << ' '; 38 | } 39 | std::cout << '\n'; 40 | 41 | return 0; 42 | } -------------------------------------------------------------------------------- /6 - Core & Library Features/jthread_interrupt_argument.cpp: -------------------------------------------------------------------------------- 1 | // Run with in g++ 2 | /* 3 | g++ jthread_interrupt_argument.cpp -Wall -Wextra -std=gnu++2a 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace ::std::literals; 11 | 12 | void SomeThread(std::stop_token itoken, int* value) 13 | { 14 | int v = *value; 15 | while (true) 16 | { 17 | std::this_thread::sleep_for(0.2s); 18 | if (itoken.stop_requested()) 19 | break; 20 | std::cout << "v = " << v << std::endl; 21 | } 22 | } 23 | 24 | int main() 25 | { 26 | std::cout << std::endl; 27 | 28 | int v = 100; 29 | std::jthread jt = std::jthread(&SomeThread, (int*)&v); 30 | 31 | std::this_thread::sleep_for(1s); 32 | 33 | std::cerr << std::endl; 34 | std::cerr << "Main thread interrupts both jthreads" << std::endl; 35 | 36 | jt.request_stop(); 37 | 38 | std::cout << std::endl; 39 | 40 | return 0; 41 | } -------------------------------------------------------------------------------- /5 - Format/hello_world.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl.exe hello_world.cpp /I fmt/include /std:c++latest /EHsc /MD /link fmt.lib 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | 10 | int main() 11 | { 12 | // Part 1 13 | // Standard C++ syntax using std::cout 14 | std::cout << "Hello, " << "world!\n"; 15 | 16 | // Python-like format string syntax using fmt 17 | fmt::print("Hello, {}!\n", "world"); 18 | 19 | // Part 2 20 | // Standard C++ syntax using std::cout 21 | std::cout << "I'd rather be " << "happy" << " than " << "right.\n"; 22 | 23 | // Python-like format string syntax using fmt 24 | fmt::print("I'd rather be {1} than {0}.\n", "right", "happy"); 25 | 26 | // Part 3 27 | int a = 1, b = 2; 28 | 29 | // Standard C++ syntax using std::cout 30 | std::cout << a << " + " << b << " = " << a + b << '\n'; 31 | 32 | // Python-like format string syntax using fmt 33 | fmt::print("{} + {} = {}", a, b, a + b); 34 | 35 | return 0; 36 | } -------------------------------------------------------------------------------- /3 - Concepts/too_specific2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct MyHouse 5 | { 6 | MyHouse() = default; // (1) 7 | MyHouse(const std::string& fam) : family(fam) 8 | { 9 | // Do nothing 10 | } 11 | 12 | operator bool() 13 | { 14 | return !family.empty(); // (2) 15 | } 16 | 17 | std::string family = ""; 18 | }; 19 | 20 | void needInt(int i) 21 | { 22 | std::cout << "int: " << i << std::endl; 23 | } 24 | 25 | int main() 26 | { 27 | std::cout << std::boolalpha << std::endl; 28 | 29 | MyHouse firstHouse; 30 | if (!firstHouse) 31 | { 32 | std::cout << "The firstHouse is still empty." << std::endl; 33 | }; 34 | 35 | MyHouse secondHouse("grimm"); 36 | if (secondHouse) 37 | { 38 | std::cout << "Family grimm lives in secondHouse." << std::endl; 39 | } 40 | 41 | std::cout << std::endl; 42 | 43 | needInt(firstHouse); // (3) 44 | needInt(secondHouse); // (3) 45 | 46 | std::cout << std::endl; 47 | } -------------------------------------------------------------------------------- /5 - Format/alignment.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl.exe alignment.cpp /I fmt/include /std:c++latest /EHsc /MD /link fmt.lib 4 | */ 5 | 6 | #include 7 | 8 | int main() 9 | { 10 | // Result: "left aligned " 11 | fmt::print("{:<30}\n", "left aligned"); 12 | // Result: " right aligned" 13 | fmt::print("{:>30}\n", "right aligned"); 14 | // Result: " centered " 15 | fmt::print("{:^30}\n", "centered"); 16 | // Result: "***********centered***********" 17 | fmt::print("{:*^30}\n", "centered"); 18 | 19 | // Result: "3.1" 20 | fmt::print("{:.{}f}\n", 3.14, 1); 21 | // Result: "3.2" 22 | fmt::print("{:.{}f}\n", 3.16, 1); 23 | 24 | // Result: "+3.140000; -3.140000" 25 | fmt::print("{:+f}; {:+f}\n", 3.14, -3.14); 26 | // Result: " 3.140000; -3.140000" 27 | fmt::print("{: f}; {: f}\n", 3.14, -3.14); 28 | // Result: "3.140000; -3.140000" 29 | fmt::print("{:-f}; {:-f}\n", 3.14, -3.14); 30 | 31 | return 0; 32 | } -------------------------------------------------------------------------------- /6 - Core & Library Features/calendar.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl.exe calendar.cpp /I date/include /std:c++latest /EHsc 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | using namespace date; 12 | 13 | inline int number_of_days(const sys_days& first, const sys_days& last) 14 | { 15 | return (last - first).count(); 16 | } 17 | 18 | int main() 19 | { 20 | auto d1 = 2018_y / mar / 27; 21 | auto d2 = 27_d / mar / 2018; 22 | auto d3 = mar / 27 / 2018; 23 | year_month_day today = floor(std::chrono::system_clock::now()); 24 | 25 | assert(d1 == d2); 26 | assert(d2 == d3); 27 | // assert(d3 == today); 28 | 29 | auto ymdl = year_month_day_last(today.year(), month_day_last{month{2}}); 30 | auto last_day_feb = year_month_day{ymdl}; 31 | 32 | // assert(last_day_feb == 2018_y / feb / 28); // for 2018 33 | 34 | auto days = number_of_days(2018_y / apr / 1, 2018_y / dec / 25); 35 | 36 | assert(days == 268); 37 | 38 | return 0; 39 | } -------------------------------------------------------------------------------- /3 - Concepts/equal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | concept SameHelper = std::is_same::value; 5 | 6 | template 7 | concept same_as = SameHelper && SameHelper; 8 | 9 | template 10 | concept Equal = requires(T a, T b) 11 | { 12 | { a == b } -> same_as; 13 | { a != b } -> same_as; 14 | }; 15 | 16 | bool areEqual(Equal auto a, Equal auto b) // (1) 17 | { 18 | return a == b; 19 | } 20 | 21 | /* 22 | struct WithoutEqual 23 | { 24 | bool operator==(const WithoutEqual& other) = delete; 25 | }; 26 | 27 | struct WithoutUnequal 28 | { 29 | bool operator!=(const WithoutUnequal& other) = delete; 30 | }; 31 | */ 32 | 33 | int main() 34 | { 35 | std::cout << std::boolalpha << std::endl; 36 | 37 | std::cout << "areEqual(1, 5): " << areEqual(1, 5) << std::endl; 38 | 39 | /* 40 | bool res = areEqual(WithoutEqual(), WithoutEqual()); 41 | bool res2 = areEqual(WithoutUnequal(), WithoutUnequal()); 42 | */ 43 | 44 | std::cout << std::endl; 45 | } -------------------------------------------------------------------------------- /4 - Coroutines/fibonacci.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl fibonacci.cpp /std:c++latest /await /EHsc 4 | */ 5 | 6 | // References: https://github.com/roger-dv/cpp20-coro-generator 7 | 8 | #include "generator.hpp" 9 | 10 | #include 11 | #include 12 | 13 | using coro_exp::generator; 14 | 15 | static const double demo_ceiling = 10E44; 16 | 17 | generator fibonacci(const double ceiling) 18 | { 19 | double j = 0; 20 | double i = 1; 21 | co_yield j; 22 | 23 | if (ceiling > j) 24 | { 25 | do 26 | { 27 | co_yield i; 28 | double tmp = i; 29 | i += j; 30 | j = tmp; 31 | } while (i <= ceiling); 32 | } 33 | } 34 | 35 | int main() 36 | { 37 | std::cout << "Example program using C++20 coroutine to implement a " 38 | "Fibonacci Sequence generator" 39 | << '\n'; 40 | 41 | auto iter = fibonacci(demo_ceiling); 42 | while (iter.next()) 43 | { 44 | const auto value = iter.getValue(); 45 | std::cout << value << '\n'; 46 | } 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 C++ Korea 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /2 - Ranges/range_comprehension2.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl.exe range_comprehension2.cpp /I ../../range-v3/include /std:c++latest /permissive- /experimental:preprocessor 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | 10 | using namespace ranges; 11 | 12 | int main() 13 | { 14 | std::cout << std::endl; 15 | 16 | // triples =[(x, y, z)|z <-[1..], x <-[1..z],y <-[x..z] ,x^2 + y^2 == z^2] 17 | 18 | auto triples = view::for_each(view::ints(1), [](int z) { 19 | return view::for_each(view::ints(1, z), [=](int x) { 20 | return view::for_each(view::ints(x, z), [=](int y) { 21 | return yield_if(x * x + y * y == z * z, 22 | std::make_tuple(x, y, z)); 23 | }); 24 | }); 25 | }); 26 | 27 | ranges::for_each( 28 | triples | view::take_while([](std::tuple nums) { 29 | return std::get<0>(nums) < 100; 30 | }), 31 | [](std::tuple nums) { 32 | std::cout << "(" << std::get<0>(nums) << ", " << std::get<1>(nums) 33 | << ", " << std::get<2>(nums) << ")\n"; 34 | }); 35 | 36 | std::cout << "\n\n"; 37 | 38 | return 0; 39 | } -------------------------------------------------------------------------------- /2 - Ranges/function_composition.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl.exe function_composition.cpp /I ../../range-v3/include /std:c++latest /permissive- /experimental:preprocessor 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | using namespace ranges; 12 | 13 | int main() 14 | { 15 | std::cout << std::endl; 16 | 17 | // odds = takeWhile (< 1000) . filter odd . map (^2) 18 | // odds [1..] -- [1, 9, 25, ... , 841, 961] 19 | 20 | auto odds = view::transform([](int i) { return i * i; }) | 21 | view::remove_if([](int i) { return i % 2 == 0; }) | 22 | view::take_while([](int i) { return i < 1000; }); 23 | auto oddNumbers = view::ints(1) | odds; 24 | 25 | ranges::for_each(oddNumbers, [](int i) { std::cout << i << " "; }); 26 | 27 | std::cout << "\n\n"; 28 | 29 | // total = sum $ take 100 $ map (\x -> x*x) [100..1000] -- 2318350 30 | 31 | auto total = ranges::accumulate( 32 | view::ints(100, 1000) | view::transform([](int x) { return x * x; }) | 33 | view::take(100), 34 | 0); 35 | 36 | std::cout << "total: " << total << std::endl; 37 | 38 | std::cout << std::endl; 39 | 40 | return 0; 41 | } -------------------------------------------------------------------------------- /1 - Modules/simple_main.cpp: -------------------------------------------------------------------------------- 1 | // Run with in clang++ 2 | /* 3 | clang++ -std=c++2a -fmodules-ts --precompile simple_math.cppm -o simple_math.pcm 4 | clang++ -std=c++2a -fmodules-ts -c simple_math.pcm -o simple_math.pcm.o 5 | clang++ -std=c++2a -fmodules-ts -c simple_math.cpp -fmodule-file=simple_math.pcm -o simple_math.o 6 | clang++ -std=c++2a -fmodules-ts -c simple_main.cpp -fmodule-file=simple_math.pcm -o simple_main.o 7 | clang++ simple_math.pcm simple_math.o simple_main.o -o simple_main 8 | */ 9 | 10 | // Run with in cl 11 | /* 12 | cl.exe /std:c++latest /experimental:module /TP /EHsc /MD /c simple_math.cppm /module:interface /Fo: simple_math.pcm.obj /module:output simple_math.pcm 13 | cl.exe /std:c++latest /experimental:module /TP /EHsc /MD /c simple_math.cpp /module:reference simple_math.pcm /Fo: simple_math.obj 14 | cl.exe /std:c++latest /experimental:module /TP /EHsc /MD /c simple_main.cpp /module:reference simple_math.pcm /Fo: simple_main.obj 15 | cl.exe simple_math.obj simple_main.obj simple_math.pcm.obj 16 | */ 17 | 18 | import std.core; 19 | import simple_math; 20 | 21 | int main() 22 | { 23 | std::vector v; 24 | v.emplace_back(add(100, 200)); 25 | v.emplace_back(add(30, 40)); 26 | 27 | std::copy(v.begin(), v.end(), std::ostream_iterator(std::cout, "\n")); 28 | 29 | return 0; 30 | } -------------------------------------------------------------------------------- /6 - Core & Library Features/jthread_interrupt.cpp: -------------------------------------------------------------------------------- 1 | // Run with in g++ 2 | /* 3 | g++ jthread_interrupt.cpp -Wall -Wextra -std=gnu++2a 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace ::std::literals; 11 | 12 | int main() 13 | { 14 | std::cout << std::endl; 15 | 16 | std::jthread nonInterruptable([] { // (1) 17 | int counter{0}; 18 | while (counter < 10) 19 | { 20 | std::this_thread::sleep_for(0.2s); 21 | std::cerr << "nonInterruptable: " << counter << std::endl; 22 | ++counter; 23 | } 24 | }); 25 | 26 | std::jthread interruptable([](std::stop_token itoken) { // (2) 27 | int counter{0}; 28 | while (counter < 10) 29 | { 30 | std::this_thread::sleep_for(0.2s); 31 | if (itoken.stop_requested()) 32 | return; // (3) 33 | std::cerr << "interruptable: " << counter << std::endl; 34 | ++counter; 35 | } 36 | }); 37 | 38 | std::this_thread::sleep_for(1s); 39 | 40 | std::cerr << std::endl; 41 | std::cerr << "Main thread interrupts both jthreads" << std::endl; 42 | nonInterruptable.request_stop(); 43 | interruptable.request_stop(); // (4) 44 | 45 | std::cout << std::endl; 46 | 47 | return 0; 48 | } -------------------------------------------------------------------------------- /4 - Coroutines/suspend_always.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl suspend_always.cpp /std:c++latest /await /EHsc 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | class return_ignore final 10 | { 11 | public: 12 | class promise_type final 13 | { 14 | public: 15 | auto initial_suspend() noexcept 16 | { 17 | return std::experimental::suspend_never{}; 18 | } 19 | 20 | auto final_suspend() noexcept 21 | { 22 | return std::experimental::suspend_never{}; 23 | } 24 | 25 | void return_void() noexcept 26 | { 27 | // nothing to do because this is `void` return 28 | } 29 | 30 | void unhandled_exception() noexcept(false) 31 | { 32 | std::terminate(); // customize this part 33 | } 34 | 35 | promise_type* get_return_object() noexcept 36 | { 37 | return this; 38 | } 39 | }; 40 | 41 | public: 42 | return_ignore(const promise_type*) noexcept 43 | { 44 | // the type truncates all given info about its frame 45 | } 46 | }; 47 | 48 | using namespace std; 49 | namespace coro = std::experimental; 50 | 51 | auto example() -> return_ignore 52 | { 53 | puts("step 1"); 54 | co_await coro::suspend_always{}; 55 | puts("step 2"); 56 | } 57 | 58 | int main(int, char* []) 59 | { 60 | example(); 61 | puts("step 3"); 62 | 63 | return 0; 64 | } -------------------------------------------------------------------------------- /4 - Coroutines/suspend_never.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl suspend_never.cpp /std:c++latest /await /EHsc 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | class return_ignore final 10 | { 11 | public: 12 | class promise_type final 13 | { 14 | public: 15 | auto initial_suspend() noexcept 16 | { 17 | return std::experimental::suspend_never{}; 18 | } 19 | 20 | auto final_suspend() noexcept 21 | { 22 | return std::experimental::suspend_never{}; 23 | } 24 | 25 | void return_void() noexcept 26 | { 27 | // nothing to do because this is `void` return 28 | } 29 | 30 | void unhandled_exception() noexcept(false) 31 | { 32 | std::terminate(); // customize this part 33 | } 34 | 35 | promise_type* get_return_object() noexcept 36 | { 37 | return this; 38 | } 39 | }; 40 | 41 | public: 42 | return_ignore(const promise_type*) noexcept 43 | { 44 | // the type truncates all given info about its frame 45 | } 46 | }; 47 | 48 | using namespace std; 49 | namespace coro = std::experimental; 50 | 51 | auto example() -> return_ignore 52 | { 53 | puts("step 1"); 54 | co_await coro::suspend_never{}; 55 | puts("step 2"); 56 | } 57 | 58 | int main(int, char* []) 59 | { 60 | example(); 61 | puts("step 3"); 62 | 63 | return 0; 64 | } -------------------------------------------------------------------------------- /1 - Modules/simple_main_template.cpp: -------------------------------------------------------------------------------- 1 | // Run with in clang++ 2 | /* 3 | clang++ -std=c++2a -fmodules-ts --precompile simple_math_template.cppm -o simple_math_template.pcm 4 | clang++ -std=c++2a -fmodules-ts -c simple_math_template.pcm -o simple_math_template.pcm.o 5 | clang++ -std=c++2a -fmodules-ts -c simple_main_template.cpp -fmodule-file=simple_math_template.pcm -o simple_main_template.o 6 | clang++ simple_math_template.pcm simple_main_template.o -o simple_main_template 7 | */ 8 | 9 | // Run with in cl 10 | /* 11 | cl.exe /std:c++latest /experimental:module /TP /EHsc /MD /c simple_math_template.cppm /module:interface /Fo: simple_math_template.pcm.obj /module:output simple_math_template.pcm 12 | cl.exe /std:c++latest /experimental:module /TP /EHsc /MD /c simple_main_template.cpp /module:reference simple_math_template.pcm /Fo: simple_main_template.obj 13 | cl.exe simple_main_template.obj simple_math_template.pcm.obj 14 | */ 15 | 16 | import std.core; 17 | import simple_math; 18 | 19 | int main() 20 | { 21 | std::vector v1; 22 | v1.emplace_back(add(100, 200)); 23 | v1.emplace_back(add(30, 40)); 24 | 25 | std::copy(v1.begin(), v1.end(), std::ostream_iterator(std::cout, "\n")); 26 | 27 | std::vector v2; 28 | v2.emplace_back(add("Hello", " World!")); 29 | v2.emplace_back(add("Happy", " Weekend!")); 30 | 31 | std::copy(v2.begin(), v2.end(), std::ostream_iterator(std::cout, "\n")); 32 | 33 | return 0; 34 | } -------------------------------------------------------------------------------- /6 - Core & Library Features/spaceship_operator.cpp: -------------------------------------------------------------------------------- 1 | // Run with in cl 2 | /* 3 | cl.exe spaceship_operator.cpp /std:c++latest /EHsc 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | class Rectangle 10 | { 11 | public: 12 | Rectangle(int x, int y) : m_x(x), m_y(y) 13 | { 14 | // Do nothing 15 | } 16 | 17 | int GetArea() const 18 | { 19 | return m_x * m_y; 20 | } 21 | 22 | std::strong_ordering operator<=>(const Rectangle& r) const 23 | { 24 | if (GetArea() == r.GetArea() && m_x <=> r.m_x == 0 && m_y <=> r.m_y == 0) 25 | { 26 | return std::strong_ordering::equal; 27 | } 28 | 29 | if (m_x <=> r.m_x == 0) 30 | { 31 | return m_y <=> r.m_y; 32 | } 33 | 34 | return m_x <=> r.m_x; 35 | } 36 | 37 | // std::weak_ordering operator<=>(const Rectangle& r) const 38 | // { 39 | // if (GetArea() == r.GetArea()) 40 | // { 41 | // return std::weak_ordering::equivalent; 42 | // } 43 | 44 | // return GetArea() > r.GetArea(); 45 | // } 46 | 47 | private: 48 | int m_x, m_y; 49 | }; 50 | 51 | int main() 52 | { 53 | Rectangle r1(8, 2); 54 | Rectangle r2(4, 4); 55 | Rectangle r3(2, 2); 56 | Rectangle r4(8, 8); 57 | 58 | std::cout << std::boolalpha << (r1<=>r2 == 0) << '\n'; 59 | std::cout << std::boolalpha << (r1<=>r3 > 0) << '\n'; 60 | std::cout << std::boolalpha << (r1<=>r4 < 0) << '\n'; 61 | 62 | return 0; 63 | } -------------------------------------------------------------------------------- /1 - Modules/simple_main_overloading.cpp: -------------------------------------------------------------------------------- 1 | // Run with in clang++ 2 | /* 3 | clang++ -std=c++2a -fmodules-ts --precompile simple_math_overloading.cppm -o simple_math_overloading.pcm 4 | clang++ -std=c++2a -fmodules-ts -c simple_math_overloading.pcm -o simple_math_overloading.pcm.o 5 | clang++ -std=c++2a -fmodules-ts -c simple_math_overloading.cpp -fmodule-file=simple_math_overloading.pcm -o simple_math_overloading.o 6 | clang++ -std=c++2a -fmodules-ts -c simple_main_overloading.cpp -fmodule-file=simple_math_overloading.pcm -o simple_main_overloading.o 7 | clang++ simple_math_overloading.pcm simple_math_overloading.o simple_main_overloading.o -o simple_main_overloading 8 | */ 9 | 10 | // Run with in cl 11 | /* 12 | cl.exe /std:c++latest /experimental:module /TP /EHsc /MD /c simple_math_overloading.cppm /module:interface /Fo: simple_math_overloading.pcm.obj /module:output simple_math_overloading.pcm 13 | cl.exe /std:c++latest /experimental:module /TP /EHsc /MD /c simple_math_overloading.cpp /module:reference simple_math_overloading.pcm /Fo: simple_math_overloading.obj 14 | cl.exe /std:c++latest /experimental:module /TP /EHsc /MD /c simple_main_overloading.cpp /module:reference simple_math_overloading.pcm /Fo: simple_main_overloading.obj 15 | cl.exe simple_math_overloading.obj simple_main_overloading.obj simple_math_overloading.pcm.obj 16 | */ 17 | 18 | import std.core; 19 | import simple_math; 20 | 21 | int main() 22 | { 23 | std::vector v; 24 | v.emplace_back(add(100, 200)); 25 | v.emplace_back(add(30, 40, 50)); 26 | 27 | std::copy(v.begin(), v.end(), std::ostream_iterator(std::cout, "\n")); 28 | 29 | return 0; 30 | } -------------------------------------------------------------------------------- /6 - Core & Library Features/endian.cpp: -------------------------------------------------------------------------------- 1 | // Run with in g++ 2 | /* 3 | g++ endian.cpp -Wall -Wextra -std=gnu++2a 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | std::string HEX__1(const T& value, size_t value_size = sizeof(T)) 12 | { 13 | using namespace std; 14 | uint8_t* buffer = (uint8_t*)(&value); 15 | char converted[value_size * 2 + 1]; 16 | 17 | if (endianess == std::endian::big) 18 | { 19 | for (size_t i = 0; i < value_size; ++i) 20 | { 21 | sprintf(&converted[i * 2], "%02X", buffer[i]); 22 | } 23 | } 24 | else 25 | { 26 | for (size_t i = 0; i < value_size; ++i) 27 | { 28 | sprintf(&converted[i * 2], "%02X", buffer[value_size - 1 - i]); 29 | } 30 | } 31 | 32 | return converted; 33 | } 34 | 35 | int main() 36 | { 37 | { 38 | uint8_t a = 0x10; 39 | std::cout << HEX__1(a) << std::endl; 40 | if (HEX__1(a) != "10") 41 | { 42 | throw std::runtime_error(""); 43 | } 44 | } 45 | { 46 | int32_t a = -128; 47 | std::cout << HEX__1(a) << std::endl; 48 | if (HEX__1(a) != "FFFFFF80") 49 | { 50 | throw std::runtime_error(""); 51 | } 52 | } 53 | { 54 | uint64_t a = 0x0000000000000102; 55 | std::cout << HEX__1(a) << std::endl; 56 | if (HEX__1(a) != "0000000000000102") 57 | { 58 | throw std::runtime_error(""); 59 | } 60 | } 61 | { 62 | double a = 1; 63 | std::cout << HEX__1(a) << std::endl; 64 | if (HEX__1(a) != "3FF0000000000000") 65 | { 66 | throw std::runtime_error(""); 67 | } 68 | } 69 | std::cout << "------------------" << std::endl; 70 | { 71 | uint64_t a = 0; 72 | std::cout << HEX__1(a) << std::endl; 73 | if (HEX__1(a) != "0000000000000000") 74 | { 75 | throw std::runtime_error(""); 76 | } 77 | } 78 | 79 | return 0; 80 | } -------------------------------------------------------------------------------- /4 - Coroutines/generator.hpp: -------------------------------------------------------------------------------- 1 | // References: https://github.com/roger-dv/cpp20-coro-generator 2 | 3 | #ifndef GENERATOR_HPP 4 | #define GENERATOR_HPP 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace coro_exp 11 | { 12 | template 13 | class generator 14 | { 15 | public: 16 | struct promise_type; 17 | using handle_type = std::experimental::coroutine_handle; 18 | 19 | private: 20 | handle_type coro; 21 | 22 | public: 23 | explicit generator(handle_type h) : coro(h) 24 | { 25 | } 26 | generator(const generator &) = delete; 27 | generator(generator &&oth) noexcept : coro(oth.coro) 28 | { 29 | oth.coro = nullptr; 30 | } 31 | generator &operator=(const generator &) = delete; 32 | generator &operator=(generator &&other) noexcept 33 | { 34 | coro = other.coro; 35 | other.coro = nullptr; 36 | return *this; 37 | } 38 | ~generator() 39 | { 40 | if (coro) 41 | { 42 | coro.destroy(); 43 | } 44 | } 45 | 46 | bool next() 47 | { 48 | coro.resume(); 49 | return !coro.done(); 50 | } 51 | 52 | T getValue() 53 | { 54 | return coro.promise().current_value; 55 | } 56 | 57 | struct promise_type 58 | { 59 | private: 60 | T current_value{}; 61 | friend class generator; 62 | 63 | public: 64 | promise_type() = default; 65 | ~promise_type() = default; 66 | promise_type(const promise_type &) = delete; 67 | promise_type(promise_type &&) = delete; 68 | promise_type &operator=(const promise_type &) = delete; 69 | promise_type &operator=(promise_type &&) = delete; 70 | 71 | auto initial_suspend() 72 | { 73 | return std::experimental::suspend_always{}; 74 | } 75 | 76 | auto final_suspend() 77 | { 78 | return std::experimental::suspend_always{}; 79 | } 80 | 81 | auto get_return_object() 82 | { 83 | return generator{handle_type::from_promise(*this)}; 84 | } 85 | 86 | auto return_void() 87 | { 88 | return std::experimental::suspend_never{}; 89 | } 90 | 91 | auto yield_value(T some_value) 92 | { 93 | current_value = some_value; 94 | return std::experimental::suspend_always{}; 95 | } 96 | 97 | void unhandled_exception() 98 | { 99 | std::exit(1); 100 | } 101 | }; 102 | }; 103 | 104 | } // namespace coro_exp 105 | 106 | #endif // GENERATOR_HPP -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # C++20 스터디 2 | 3 | 2020년 상반기에 진행하는 C++20 스터디 관련 자료입니다. 4 | 5 | - 진행 : [옥찬호](https://github.com/utilForever) (utilForever@gmail.com) 6 | - 날짜 : 토요일 또는 일요일 오전 11시 ~ 오후 1시 7 | - 장소 : 토즈 강남 지역 (강남 / 교대 / 양재 / 선릉) 8 | - 비용 : 7만원 (1만원 * 7회) 9 | - 인원 : 최대 10명 10 | 11 | ## 목표 12 | 13 | 이번 스터디에서는 C++11 이상의 변화가 예상되는 **C++20 표준**의 주요 기능을 살펴 봅니다. 14 | 15 | ## 진행 방식 16 | 17 | - 각 주에 진행하는 내용과 관련해 동영상을 미리 시청합니다. 18 | - 스터디 시간에는 동영상을 보면서 궁금했던 부분을 질문/답변하거나 관련 내용을 리뷰합니다. 19 | - 예제 코드를 살펴 보며 사용법이나 세부 사항들을 익힙니다. 20 | - 스터디 이후에 리뷰한 내용과 예제 코드를 Github에 업로드합니다. 21 | 22 | ## 일정 23 | 24 | - 2월 2일 **(일요일)** : Modules 25 | - [C++ References: Modules](https://en.cppreference.com/w/cpp/language/modules) 26 | - [C++20: Modules](https://www.modernescpp.com/index.php/c-20-modules) 27 | - [CppCon 2018: Nathan Sidwell "C++ Modules"](https://www.youtube.com/watch?v=xi2lTaC5p0I) 28 | - [CppCon 2018: John Lakos "C++ Modules and Large-Scale Development"](https://www.youtube.com/watch?v=K_fTl_hIEGY) 29 | - [CppCon 2019: Gabriel Dos Reis "Programming with C++ Modules: Guide for the Working"](https://www.youtube.com/watch?v=tjSuKOz5HK4) 30 | - [CppCon 2019: Nathan Sidwell "Converting to C++20 Modules"](https://www.youtube.com/watch?v=KVsWIEw3TTw) 31 | - [CppCon 2019: Boris Kolpackov "Practical C++ Modules"](https://www.youtube.com/watch?v=szHV6RdQdg8) 32 | - [C++ Modules conformance improvements with MSVC in Visual Studio 2019 16.5](https://devblogs.microsoft.com/cppblog/c-modules-conformance-improvements-with-msvc-in-visual-studio-2019-16-5/) 33 | - 2월 8일 **(토요일)** : Ranges 34 | - [C++ References: Ranges library](https://en.cppreference.com/w/cpp/ranges) 35 | - [Github repository: range-v3](https://github.com/ericniebler/range-v3) 36 | - [range-v3: User Manual](https://ericniebler.github.io/range-v3) 37 | - [Ranges for The C++ Standard Library](https://channel9.msdn.com/Events/Channel9-Korea/cplusplus/Ranges-for-The-C-Standard-Library) 38 | - [CppCon 2015: Eric Niebler "Ranges for the Standard Library"](https://www.youtube.com/watch?v=mFUXNMfaciE) 39 | - [C++Now 2019: Jeff Garland "Using C++20 Ranges Effectively"](https://www.youtube.com/watch?v=VmWS-9idT3s) 40 | - 2월 16일 **(일요일)** : Concepts 41 | - [C++ References: Constraints and concepts](https://en.cppreference.com/w/cpp/language/constraints) 42 | - [C++20: Concepts, the Details](https://www.modernescpp.com/index.php/c-20-concepts-the-details) 43 | - [C++ Core Guidelines: Rules for the Usage of Concepts](https://www.modernescpp.com/index.php/c-core-guidelines-rules-for-the-usage-of-concepts-2) 44 | - [CppCon 2018: Bjarne Stroustrup "Concepts: The Future of Generic Programming"](https://www.youtube.com/watch?v=HddFGPTAmtU) 45 | - [CppCon 2018: Andrew Sutton "Concepts in 60: Everything you need to know and nothing you don't"](https://www.youtube.com/watch?v=ZeU6OPaGxwM) 46 | - [CppCon 2019: Rainer Grimm "Concepts in C++20: Revolution or Evolution"](https://www.youtube.com/watch?v=BXBnAmqZvpo) 47 | - [CppCon 2019: Saar Raz "C++20 Concepts: A Day in the Life"](https://www.youtube.com/watch?v=qawSiMIXtE4) 48 | - 2월 22일 **(토요일)** : Coroutines 49 | - [C++ References: Coroutines](https://en.cppreference.com/w/cpp/language/coroutines) 50 | - [Github repository: cppcoro](https://github.com/lewissbaker/cppcoro) 51 | - [Github repository: coroutine](https://github.com/luncliff/coroutine) 52 | - [Github repository: coro](https://github.com/Quuxplusone/coro) 53 | - [C++ Standard Proposal: N4402](https://isocpp.org/files/papers/N4402.pdf) 54 | - [C++ links: Coroutines](https://gist.github.com/MattPD/9b55db49537a90545a90447392ad3aeb) 55 | - [C++20: Coroutines](https://www.modernescpp.com/index.php/coroutines) 56 | - [Your First C++ Coroutines](https://blog.panicsoftware.com/your-first-coroutine/) 57 | - [C++ Korea 제5회 세미나 - C++ Coroutines 알아보기; 접근법, 컴파일러, 그리고 이슈들](https://github.com/CppKorea/CppKoreaSeminar5th/blob/master/5%20-%20C%2B%2B%20Coroutine%20%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0%3B%20%EC%A0%91%EA%B7%BC%EB%B2%95%2C%20%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%AC%2C%20%EA%B7%B8%EB%A6%AC%EA%B3%A0%20%EC%9D%B4%EC%8A%88/%5BC%2B%2B%20Korea%205th%20Seminar%5D%20C%2B%2B%20Coroutine%20%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0%3B%20%EC%A0%91%EA%B7%BC%EB%B2%95%2C%20%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%AC%2C%20%EA%B7%B8%EB%A6%AC%EA%B3%A0%20%EC%9D%B4%EC%8A%88%EB%93%A4.pdf) 58 | - [C++ Korea 제6회 세미나 - System API와 Coroutine 결합하기](https://www.youtube.com/watch?v=F6E_cLOIe-U) 59 | - [CppCon 2016: James McNellis "Introduction to C++ Coroutines"](https://www.youtube.com/watch?v=ZTqHjjm86Bw) 60 | - [CppCon 2016: Gor Nishanov "C++ Coroutines: Under the covers"](https://www.youtube.com/watch?v=8C8NnE1Dg4A) 61 | - [CppCon 2017: Toby Allsopp "Coroutines: what can't they do?"](https://www.youtube.com/watch?v=mlP1MKP8d_Q) 62 | - [CppCon 2019: Anthony Williams "Concurrency in C++20 and Beyond"](https://www.youtube.com/watch?v=jozHW_B3D4U) 63 | - [C++20 Coroutines: Introduction - Marcin Grzebieluch - code::dive 2019](https://www.youtube.com/watch?v=vDA925C55F0) 64 | - ["Exploring C++20 Coroutines" by Justin Durkan](https://www.youtube.com/watch?v=RhXaKOe3JZM) 65 | - [Core C++ 2019 :: Yehezkel Bernat :: Coroutines - the future of future](https://www.youtube.com/watch?v=1tQfcPnHeRY) 66 | - 3월 1일 **(일요일)** : `std::format` 67 | - [C++ References: Formatting library](https://en.cppreference.com/w/cpp/utility/format) 68 | - [Github repository: fmt](https://github.com/fmtlib/fmt) 69 | - [Github repository: spdlog](https://github.com/gabime/spdlog) 70 | - [std::format in C++20](https://www.zverovich.net/2019/07/23/std-format-cpp20.html) 71 | - [CppCon 2017: Victor Zverovich "A modern formatting library for C++"](https://www.youtube.com/watch?v=ptba_AqFYCM) 72 | - [C++ Weekly - Ep 135 - {fmt} is Addictive! Using {fmt} and spdlog](https://www.youtube.com/watch?v=KeS1ehp9IiI) 73 | - 3월 7일 **(토요일)** : Core & Library features 74 | - [C++ References: consteval](https://en.cppreference.com/w/cpp/language/consteval) 75 | - [C++ References: operator<=>](https://en.cppreference.com/w/cpp/utility/compare/three_way_comparable) 76 | - [C++ References: std::span](https://en.cppreference.com/w/cpp/container/span) 77 | - [C++ References: std::endian](https://en.cppreference.com/w/cpp/types/endian) 78 | - [C++ References: std::bit_cast](https://en.cppreference.com/w/cpp/numeric/bit_cast) 79 | - [C++ References: std::atomic_ref](https://en.cppreference.com/w/cpp/atomic/atomic_ref) 80 | - [C++ References: std::jthread](https://en.cppreference.com/w/cpp/thread/jthread) 81 | - [C++ References: Date and time utilities](https://en.cppreference.com/w/cpp/chrono) 82 | --------------------------------------------------------------------------------