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::string
using pipeline operator andstd::ranges::to<>
.
- 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)
- 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>
#endif
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));
#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)...);
}