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); });- 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.
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()andtypeid().name().
log.h- definition
- function-style definition
LOG(...)using macro in C.
parse.hpp- definition
- unit tests
- easily split a comma-separated
std::string.
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- definition
- unit tests
free()function implementation to release allocated resources.
trimstr.hpp- definition
- unit tests
- trim a
std::stringusing pipeline operator andstd::ranges::to<>.
- Consider the
&and&&operator overloads either with const qualifications or not as "invoked with"- For example,
&concrete_instanceshall 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)
- The function with the signature
- 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 lvaluestd::string str = std::move(another_std_str);
In this case,std::move(std::string&& src)is "invoked with" a (pure) rvalue
- For example,
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> {};#if defined(__has_include) && __has_include(<version>)
#include <version>
#endifconsteval 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));#include <iostream>
#include "unroll.hpp"
int main(void) {
util::iife::unroll<2>([]{ std::puts("Hello C++ 20!"); });
return 0;
}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;#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)...};
}template<typename Fn, typename... Args>
concept my_invocable = requires (Fn&& fn, Args&&... args) {
std::invoke(std::forward<Fn>(fn), std::forward<Args>(args)...);
}