CPP23 Incomplete Quick Look Jan 2023 Q1
CPP23: c++23 Incomplete Quick Look, January 2023, Q1.
January is the first month of the new year, what will c++23 look like?
All code are passed by g++(gcc) compiler.
Example
#include <utxcpp/core.hpp> #include <vector> #include <numeric> class fizz_box { private: int x, y, z, w; std::vector<int> vector; public: fizz_box(int x, int y, int z, int w): x{x}, y{y}, z{z}, w{w}, vector(x*y*z*w) { std::iota(vector.begin(), vector.end(), 1); } void print_all() { utx::print("------------------------------------------------------------------------"); for (int i=0; i<x; i++) { for (int j=0; j<y; j++) { for (int k=0; k<z; k++) { for (int u=0; u<w; u++) { int index = i*y*z*w + j*z*w + k*w + u; utx::printnl(vector[index], ""); } utx::print(); } utx::print(); } utx::print("------------------------------------------------------------------------"); } } // Multidimensional Subscript operator[] int operator[](int i, int j, int k, int u) { int index = i*y*z*w + j*z*w + k*w + u; return vector[index]; } }; int main() { fizz_box box{2,3,2,3}; box.print_all(); int i=1, j=2, k=1, u=1; utx::print(i,j,k,u, "=>", box[i,j,k,u]); }
Output:
------------------------------------------------------------------------ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ------------------------------------------------------------------------ 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 ------------------------------------------------------------------------ 1 2 1 1 => 35
Example
#include <iostream> class fizz_box { public: static int operator()(int x) { return x*x; } static int operator[](int x) { return x*x*x; } }; int main() { std::cout << fizz_box::operator()(3) << ' ' << fizz_box::operator[](3) << std::endl; }
Example
#include <utxcpp/core.hpp> #include <ranges> constexpr bool func() { if consteval { return true; } else { return false; } } constexpr auto fn = [] { if ! consteval { return false; } else { return true; } }; int main() try { static_assert(func() == true); utx::rt_assert(func() == false); static_assert(fn() == true); utx::rt_assert(fn() == false); } catch (std::exception & e) { utx::printe(e.what()); }
#include <utxcpp/core.hpp> int main() { // Literal suffix for std::size_t auto x = 123uz; utx::same_assert<decltype(x), std::size_t, true>{}; }
std::expected: The class template std::expected provides a way to store either of two values. An object of std::expected at any given time either holds an expected value of type T, or an unexpected value of type E. std::expected is never valueless.
std::unexpected: The class template std::unexpected represents an unexpected value stored in std::expected.
Example
#include <utxcpp/core.hpp> #include <expected> int main() { std::expected<float, int> exp{123.5}; utx::print(exp.value(), *exp); //123.5 123.5 std::expected<float, int> exp2; utx::print(exp2.has_value(), exp2.value(), *exp2); //true 0.0 0.0 exp2 = 3.14; if (exp2.has_value()) utx::print(exp2.value()); //3.14 // std::unexpected ! exp2 = std::unexpected(9); utx::print(! exp2.has_value(), exp2 == std::unexpected(9)); //true true }
Example
#include <utxcpp/core.hpp> #include <expected> int main() { std::expected<float, int> exp{2.5f}; utx::print(exp.value_or(5.2f)); //2.5 exp = std::unexpected(123); utx::print(exp.value_or(1.5f)); // 1.5 exp = 7.2f; std::expected<float, int> exp2{9.3f}; exp.swap(exp2); utx::print(exp.has_value(), exp.value(), exp2.has_value(), exp2.value()); //true 9.3 true 7.2 }
Example
#include <utxcpp/core.hpp> #include <expected> #include <type_traits> // std::is_aggregate class fizz_box { public: utx::f32 x{}; utx::string y{}; public: void print() const { utx::print("(", x, ",", y, ")"); } }; static_assert(std::is_aggregate_v<fizz_box>); int main() { std::expected<fizz_box, std::string> exp{{1.2f, "c++20"}}; utx::rt_assert(exp.has_value()); exp->print(); // operator-> exp = fizz_box{2.3f, "c++23"}; utx::rt_assert(exp.has_value()); exp->print(); // operator-> exp = std::unexpected{"no value"}; utx::rt_assert(! exp.has_value()); }
std::spanstream - The class template std::basic_spanstream implements input and output operations on streams based on fixed buffers.
At the low level, the class essentially wraps a raw device implementation of std::basic_spanbuf into a higher-level interface of std::basic_iostream. The complete interface to unique std::basic_spanbuf members is provided.
Typical implementations of std::basic_spanstream only add one member subobject: the wrapped std::basic_spanbuf.
std::basic_spanstream is derived from std::basic_iostream .
Example
#include <utxcpp/core.hpp> #include <array> #include <spanstream> #include <span> #include <string> int main() { std::array<char, 1024> array; std::span<char> span{array}; std::spanstream spanstream{span}; spanstream.write("c++23!", 6); utx::print_all(array); //c + + 2 3 ! spanstream << 1024 << "c++23!"; utx::print_all(array); //c + + 2 3 ! 1 0 2 4 c + + 2 3 ! std::string str; str.resize(1024); std::spanstream ss{std::span<char>{str}}; ss << "c++23!"; utx::print_all(str); //c + + 2 3 ! utx::print(str); //c++23! utx::print(str.data()); //c++23! }
template <class R, class F, class ... Args> constexpr R invoke_r(F && f, Args && ... args) noexcept;
Usage:
auto r = std::invoke_r<R>(func, args ...);
Convert the result to type R, if it is convertible to R.
Example
#include <functional> // std::invoke, std::invoke_r #include <utxcpp/core.hpp> #include <string_view> auto fn = [] (utx::u8 x, utx::u8 y) -> utx::u8 { return x+y; }; int main() { auto r1 = std::invoke(fn, 12, 100); auto r2 = std::invoke_r<utx::u16>(fn, 12, 100); utx::same_assert<decltype(r1), utx::u8, true>{}; utx::same_assert<decltype(r2), utx::u8, false>{}; utx::same_assert<decltype(r2), utx::u16, true>{}; utx::rt_assert(std::cmp_equal(r1, r2)); }
std::is_scoped_enum
std::is_scoped_enum_v
Example
#include <utxcpp/core.hpp> #include <type_traits> // std::is_scoped_enum, std::is_scoped_enum_v #include <atomic> class A; enum class B; enum C {}; int main() { utx::print( std::is_scoped_enum_v<A>, std::is_scoped_enum_v<B>, std::is_scoped_enum_v<C>, std::is_scoped_enum_v<int>, std::is_scoped_enum_v<std::memory_order> ); //false true false false true }
Example
#include <utxcpp/core.hpp> int main() { #ifdef b2 utx::print("b2 build is used"); #elifdef bjam utx::print("bjam build is used"); #elifndef build utx::print("no build system"); #else utx::print("unknown build system"); #endif }
Run:
b2 b2 -a define=b2 b2 -a define=bjam b2 -a define=build
Invokes undefined behavior. An implementation
may use this to optimize impossible code branches away (typically, in optimized
builds) or to trap them to prevent further execution (typically, in debug
builds).
https://en.cppreference.com/w/cpp/utility/unreachable
Example 1
#include <utxcpp/core.hpp> #include <utility> // std::unreachable namespace pk { template <utx::kspt::real_number T> inline utx::fmax sqrt(const T & x) { if (x < 0) { utx::print("a"); std::unreachable(); utx::print("b"); } utx::print("c"); return std::sqrt<utx::fmax>(x).real(); } } int main() { utx::print(pk::sqrt(9)); utx::print(pk::sqrt(-9)); } /* Output: c 3.000000 a c 0.000000 */
Example 2
#include <utxcpp/core.hpp> #include <utility> // std::unreachable int fn(int x) { switch (x) { case 1: [[fallthrough]]; case 2: return 3; default: std::unreachable(); return 7; } return 10; } int main() { utx::print(fn(1)); utx::print(fn(10000)); } /* Output: 3 9999 */
Specifies that an expression will always evaluate to true at a given point.
https://en.cppreference.com/w/cpp/language/attributes/assume
Example
#include <utxcpp/core.hpp> utx::i32 fn(utx::i32 x) { [[assume(x>0)]]; return ++x; } int main() { fn(123); // more efficient fn(-123); // less efficient }
Utxcpp Project
https://cppfx.xyz/fossil/utxcpp
cppreference c++23
https://en.cppreference.com/w/cpp/23
Boost c++ Libraries
Last revised: March 27, 2023 at 03:21:19 GMT |