Open Kwasniok opened 2 years ago
• Things To Make Sure Before Updating Your Code
• First Take a Look At Your Code • Take A Minute And Then Think About The Update Your Going To Do • If You Think The Code Need's Update • Then List Out The Updates Your Going To Do • Then Make Sure What The Section Of Code Your Going To Update • Before Updating Your Code Take A Copy Of It • If Your Adding New Features Or Updates In Your Code Make Sure The Feature And Updates Are Needed To The Code • You Need To Be Sure That The Update Or The Feature Your Adding Doesn't Make Your Code Worst Or Slow Down • Don't Do All The Updates At Once • Do It One By One And Make Sure Your Code Is Running Properly • In Every Update Make Sure Your Code Is Working And Your Updating The Right Thing Not Messing With the Correct Code Or Making The Code Slow Or Worst!
• Don't Do All The Updates At Once
Ah yes, it's a classic : D
idea: array_traits
#include <array>
#include <concepts>
template<typename T>
struct array_traits {
constexpr static bool is_array = false;
};
template<typename T, std::size_t N>
struct array_traits<std::array<T, N>> {
constexpr static bool is_array = true;
using value_type = T;
constexpr static std::size_t size {N};
};
template<typename T, typename value_type>
concept array_of_value_type = array_traits<T>::is_array && std::same_as<typename array_traits<T>::value_type, value_type>;
template<typename T>
concept empty_array = array_traits<T>::is_array && (array_traits<T>::size == 0);
template<typename T>
concept non_empty_array = array_traits<T>::is_array && (array_traits<T>::size > 0);
template<typename T, std::size_t size>
concept array_of_size = array_traits<T>::is_array && (array_traits<T>::size == size);
template<typename T, std::size_t size>
concept array_of_size_at_least = array_traits<T>::is_array && (array_traits<T>::size >= size);
template<typename T, std::size_t size>
concept array_of_size_at_most = array_traits<T>::is_array && (array_traits<T>::size <= size);
template<typename T, std::size_t low, std::size_t high>
concept array_of_size_in_range = array_traits<T>::is_array && (array_traits<T>::size >= low) && (array_traits<T>::size < high);
idea: consteval array functions
template <typename T, std::size_t N>
consteval auto sum(const std::array<T, N>& arr) {
T res{static_cast<T>(0)};
for (std::size_t i = 0; i < arr.size(); ++i) {
res += arr[i];
}
return res;
}
template <typename T, std::size_t N>
consteval auto prod(const std::array<T, N>& arr) {
T res{static_cast<T>(1)};
for (std::size_t i = 0; i < arr.size(); ++i) {
res *= arr[i];
}
return res;
}
template <typename T, std::size_t N>
consteval bool all_strictly_positive(const std::array<T, N>& arr) {
bool res = true;
for (std::size_t i = 0; i < arr.size(); ++i) {
res = res && (arr[i] > 0);
}
return res;
}
template <typename T, std::size_t N1, std::size_t N2>
consteval std::array<T, N1 + N2> concatenate(const std::array<T, N1>& arr1, const std::array<T, N2>& arr2) {
std::array<T, N1 + N2> res{};
for (std::size_t i = 0; i < N1; ++i) {
res[i] = arr1[i];
}
for (std::size_t i = 0; i < N2; ++i) {
res[N1 + i] = arr2[i];
}
return res;
}
template <typename T, std::size_t N>
consteval std::array<T, N - 1> rest(const std::array<T, N>& arr)
requires non_empty_array<std::array<T, N>>
{
static_assert(N > 0, "size must be strictly positive");
std::array<T, N - 1> res{};
for (std::size_t i = 1; i < N; ++i) {
res[i] = arr[i];
}
return res;
}
template <std::size_t pos, typename T, std::size_t N>
consteval std::array<T, N - 1> erase_at(const std::array<T, N>& arr)
requires non_empty_array<std::array<T, N>>
{
static_assert(N > 0, "size must be strictly positive");
std::array<T, N - 1> res{};
for (std::size_t i = 0; i < N - 1; ++i) {
res[i] = arr[i + (i < pos ? 0 : 1)];
}
return res;
}
idea: ~value to type promotion~
not needed: Simply use constant expressions directly in required clause.
// func<i> where i > 0
template<int i>
requires (i > 0)
func() {}
original idea:
template<typename T, T x>
struct value_to_type {
using type = T;
constexpr static T value {x};
};
template<typename T>
struct type_to_value {
constexpr static bool is_value = false;
};
template<typename T, T x>
struct type_to_value<value_to_type<T, x>> {
constexpr static bool is_value = true;
using type = T;
constexpr static T value {x};
};
template<typename T, typename U, U value>
concept is_value_equals = type_to_value<T>::is_value && (type_to_value<T>::value == value);
Tensors
Observations
std::array<T, 0>
is not empty since the constructor still takes one argument of typeint
.