Skip to content

Latest commit

 

History

History

Util

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Util

Prefer STL Algorithms over Raw Loops

void lower(std::string s) {
    for (unsigned int i = 0; i <= std::strlen(s.data()); ++i) {
        s[i] = std::lower(s[i]);
    }
}

std::transform(s.begin(), s.end(), s.begin(), [](char c) { return std::tolower(c); });

Prefer Immutable Data to Mutable Data

  • Easier to verify code when using constants.
  • Constants have higher optimization potential.
  • Constant data is data-race free by design, since mutation is a necessary condition for a data-race.

About

Contains template (generic) function in a C-style header file, providing the following functionality:

  • is_instance_of.hpp
    • definition
    • unit tests
    • identify whether an object if of a specified type.
    • comparable to isinstance() in Python.
  • is_same_type_of.hpp
    • definition
    • identify whether two objects are the same type.
    • use typeid().hash_code() and typeid().name().
  • log.h
    • definition
    • function-style definition LOG(...) using macro in C.
  • parse.hpp
  • print_list.hpp
    • definition
    • template function to print a std::list<> to console.
    • accepts a generic type of std::list<>.
  • print_range.hpp
    • definition
    • unit tests
    • template function to print a std::ranges<> to console.
    • accepts a generic type of std::ranges<>.
  • print_vec.hpp
    • definition
    • template function to print a std::vector<> to console.
    • accepts a generic type of std::vector<>.
  • safe_free.hpp
  • trimstr.hpp

cpp Language Reference and Notes

& and && overload operators thoughts experiment - Reference Qualifiers

  • Consider the & and && operator overloads either with const qualifications or not as "invoked with"
    • For example, &concrete_instance shall be considered as "such function is invoked with a lvalue"
      Consider the following example: https://github.com/XuhuaHuang/EmbeddedProgramming/blob/main/MemberFnAmpersand/MemberFnAmpersand.cpp
      • The function with the signature int& getArg()& is invoked with a mutable lvalue (left value)
      • The function with the signature int& getArg()&& is invoked with a mutable rvalue (right value)
    • Such mentality will also make sense for a normal operation like the following;
      • int* p_int = &int_on_stack;
        In this case, the & operator is "invoked with" a lvalue
      • std::string str = std::move(another_std_str);
        In this case, std::move(std::string&& src) is "invoked with" a (pure) rvalue

Arithmetic and Comparison Operators Support

template<typename Type>
struct support_stdspan_arithmetic_operators {
    using value_type = std::remove_cv_t<Type>;
public:
    inline constexpr friend std::span<value_type> operator + (std::span<value_type> lhs, const value_type n)
    {
        std::span<value_type> copy{ lhs };
        for (/* std::span<value_type>::iterator */ constexpr auto it = copy.begin(); it != copy.end(); it++) {
            *it += n;
        }
        return std::span<value_type>(copy);
    }
};

struct long_double_span_arithmetic_operators : support_stdspan_arithmetic_operators<long double> {};

struct double_span_arithmetic_operators : support_stdspan_arithmetic_operators<double> {};

template<typename Type>
struct support_stdspan_comparison_operators {
    using value_type = std::remove_cv_t<Type>;
public:
    constexpr support_stdspan_comparison_operators() = default;
    template<typename value_type>
    friend constexpr bool operator == (std::span<value_type> lhs, std::span<value_type> rhs) { return true; }
};

struct double_span_comparison_operator : support_stdspan_comparison_operators<double> {};

Include Gard

#if defined(__has_include) && __has_include(<version>)
#include <version>
#endif

Design by Introspection

consteval decltype(auto) foo(auto t) {
    if constexpr (requires{ t.foo; }) {
        return t.foo;
    } else {
        return 0;
    }
}

constexpr struct { int foo{42}; } f;
static_assert(42 == foo(f));

constexpr struct { int bar{42}; } b;
static_assert(0 == foo(b));

Immediately-Invoked Function Expression (IIFE)

#include <iostream>
#include "unroll.hpp"

int main(void) {
    util::iife::unroll<2>([]{ std::puts("Hello C++ 20!"); });
    return 0;
}

std::valarray::swap and std::addressof Implementation

void swap(valarray& _Right) noexcept {
    if (this != _STD addressof(_Right)) {
        _STD swap(_Myptr, _Right._Myptr);
        _STD swap(_Mysize, _Right._Mysize);
    }
}

_EXPORT_STD template <class _Ty>
_NODISCARD constexpr _Ty* addressof(_Ty& _Val) noexcept {
    return __builtin_addressof(_Val);
}

_EXPORT_STD template <class _Ty>
const _Ty* addressof(const _Ty&&) = delete;

Typical get_data() Function Implementation with Variadic Template Parameter Pack

#include <array>

template<typename ValueType, typename ... Params>
[[nodiscard]] std::array<ValueType, sizeof...(Params)+1> get_data(const ValueType& v1, const Params& ... params)
{
    return {v1, params...};
}

/// @brief C++17 Implementation with CTAD
template<typename ValueType, typename ... Params>
auto get_data(const ValueType& v1, const Params& ... params)
{
    return std::array{v1, params...};
}

auto get_data(auto&& ... params)
{
    return std::array{std::forward<decltype(params)>(params)...};
}

An Easy-to-read invocable Concept

template<typename Fn, typename... Args>
concept my_invocable = requires (Fn&& fn, Args&&... args) {
    std::invoke(std::forward<Fn>(fn), std::forward<Args>(args)...);
}