Showing posts with label cpp_best_practice. Show all posts
Showing posts with label cpp_best_practice. Show all posts

Jun 13, 2022

[C++] C++20 code examples

Reference:
https://www.youtube.com/watch?v=UCIKbUvEKfI


Ranges as Single Argument:

std::ranges::sort(coll);


https://en.cppreference.com/w/cpp/ranges/input_range
void print(const std::ranges::input_range auto& rg) {
    std::ranges::for_each(rg,
        [] (const auto& val) { ... });
}


Sentinels:
template<auto Val> // can be Non-Type Template Parameter(NTTP) parameters
struct EndValue{
// operator== introduces
// lhs == rhs
// rhs == lhs
// lhs != rhs
// rhs != lhs
    bool operator== (auto pos) const {
        return *pos == Val;
    }
};

std::vector coll = {42,32,12, -1, 2};

// no need as same type arguments
std::ranges::sort(coll.begin(), EndValue<-1>{});

std::ranges::subrange range{coll.begin(), EndValue<-1>{}};

print(range);
print(coll);

struct Coord {
    double x, y, z;

    // defines all 6 comparison operators
    // constexpr, noexcept, type conversions
    auto operator<=> (const Coord&) const = default;

    friend std::ostream& operator<< (std::ostream& strm, const Coord& c) {
        return strm << std::format("{}/{}/{}", c.x, c.y, c.z);
    }
};

std::array points{Coord{1,2,3}, Coord{4,5,6}, Coord{7,8,9}};
std::ranges::sort(points);
print(std::ranges::subrange{points.begin(), EndValue<Coord{4,5,6}>{}});


Views:
std::ranges::sort(std::views::counted(coll.begin(), 4));
print(coll);

// View is lazy evaluated. i.e vw is a composition of operation; not the result.
// only until its dereferenced does it doing calculation.
auto vw = coll | std::views::filter([] (const auto& v) { return v > 0; })
                            | std::views::transform([] (const auto& v) { return v*v; });

// https://en.cppreference.com/w/cpp/ranges/input_range
void print(std::ranges::input_range auto&& rg) {
    std::ranges::for_each(rg,
        [] (const auto& val) { ... });
}

print(vw); // this print has signature change to universal reference




Pipelines of Range Adaptors:
std::map<std::string, int> composer {
    {"A", 123}, {"B", 456},
};

namespace vws = std::views;

for (const auto& e : composer
    | vws::filter([](const auto& y) { return y.second >= 100;})
    | vws::take(3)
    | vws::keys) {

    ...
}



Threads:
// https://en.cppreference.com/w/cpp/thread/stop_token

#include <barrier>

void compute() {
    std::array values {1.0, 2.0, 3.0};

    std::barrier allRdy{ values.size(),
    	[&]()noexcept{print(values);}};

    std::vector<std::jthread> threads;

    for(auto idx = 0; idx < values.size(); ++idx) {
        threads.push_back(std::jthread{
            [idx, &values, &allRdy] (std::stop_token st) {
                while(!st.stop_requested()) {
                    values[idx] = std::sqrt(values[idx]);
                    ...
                    allRdy.arrive_and_wait(); // sync and print()
                }

                // ensure other threads don't wait for this anymore;
                arrRdy.arrive_and_drop();

            }});
    }
}


// std::binary_semqphore
// https://en.cppreference.com/w/cpp/thread/counting_semaphore

int inData;
std::binary_semaphore inReady{0};

// start threads to read and process values by value:
std::jthread process{ [&] (std::stop_token st) {
    while(!st.stop_requested()) {
    if (inReady.try_acquire_for(1s)) {
        int data = inData;
        ...

    }}};


for (int i = 0; i < 10; ++i) {
    inData = i;
    inReady.release();
}
std::atomic_ref<> useful for make value atomic in certain scope but not the value itself is atomic.
std::atomic now can be used as conditional variable and it is FAIR scheduled.

// std::atomic<>
// https://en.cppreference.com/w/cpp/atomic/atomic/notify_one
std::atomic.wait();



Chrono:
auto fst = 2021y / 1 / 1;
auto lst = 2021y / 12 / std::chrono::last;

// std::chrono::sys_days
for (auto d = fst; d <= lst; d+= std::chrono::months{1}) {
    std::chrono::weekday{d} == std::chrono::Monday;

}


Time zones:


#include <chrono>
auto localNow = std::chrono::current_zone() -> to_local(std::chrono::system_clock::now());
std::chrono::year_month_day{std::chrono::floor<std::chrono::days>(localNow)};

// clocks
// system_clock
// utc_clock
// gps_clock
// tai_clock
// ----

Sep 9, 2021

[C++] Safer Usage Of C++ note

Reference:
Safer Usage Of C++

CLang user manual:

https://clang.llvm.org/docs/UsersManual.html

https://clang.llvm.org/docs/ClangCommandLineReference.html


Enable flags:

-fno-exceptions
-ftrapv
-fwrapv
fsanitize=signed-integer-overflow
-Wdangling-gsl

-fno-delete-null-pointer-checks (named as such for historical reasons) that defines null pointer dereferences. With this flag, dereferences of null are never optimized away.


MiraclePtr:

https://youtu.be/ohlxw5kDn-k

https://docs.google.com/presentation/d/1QvfZXx5HdUl0IdkBcrx-NM0ua-PVcTi2jNx0Sf-n8Fo/edit#slide=id.gab22a695b8_0_1


scpptool 

is a command line tool to help enforce a memory and data race safe subset of C++. 

https://github.com/duneroadrunner/scpptool


"SaferCPlusPlus" is essentially a collection of safe data types intended to facilitate memory and data race safe C++ programming.

https://github.com/duneroadrunner/SaferCPlusPlus

https://github.com/duneroadrunner/SaferCPlusPlus-AutoTranslation2


StarScan

Heap scanning use-after-free prevention

https://source.chromium.org/chromium/chromium/src/+/master:base/allocator/partition_allocator/starscan/README.md


MiraclePtr aka raw_ptr aka BackupRefPtr

https://chromium.googlesource.com/chromium/src/+/ddc017f9569973a731a574be4199d8400616f5a5/base/memory/raw_ptr.md


Pointer Safety Ideas

https://docs.google.com/document/d/1qsPh8Bcrma7S-5fobbCkBkXWaAijXOnorEqvIIGKzc0/edit#


P1705R1

Enumerating Core Undefined Behavior

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1705r1.html


Automatic Reference Counting

https://en.wikipedia.org/wiki/Automatic_Reference_Counting


Blink GC API reference

https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md

https://docs.google.com/presentation/d/1XPu03ymz8W295mCftEC9KshH9Icxfq81YwIJQzQrvxo/edit#slide=id.p


2 basic types of memory safety

spatial:

The program will behave in a defined and safe way if it accesses memory outside valid bounds.

Examples include array bounds, struct and union field access, and iterator access.


temporal:

The program will behave in a defined and safe way if it accesses memory when that memory is not valid at the time of the access.

Examples include use after free (UAF), double-free, use before initialization, and use after move (UAM).


[[clang::lifetimebound]] 

https://clang.llvm.org/docs/AttributeReference.html#lifetimebound


ABSL

Use absl::variant Instead Of enums for state machines