Things To Add to the library #3
Replies: 5 comments 5 replies
-
int main()
{
std::string s{};
mlib::amount_t<10>.times([&](){s += "a";});
std::cout << s << "\n"; // outputs: aaaaaaaaaa
} This will be very useful and it is all happening at compile time, as after all this is a metaprogramming library! You could also do it with Here is the implementation, it doesn't need to use the namespace mlib
{
template<auto T>
struct amount
{
constexpr auto times(auto&& lambda) const;
};
template<auto T>
static constexpr auto amount_t = amount<T>{};
template<auto T>
constexpr auto amount<T>::times(auto&& lambda) const
{
lambda();
if constexpr(T - 1 != 0)
{
amount_t<T - 1>.times(lambda);
}
return true;
}
}; // namespace mlib An easy way to use it, as shown in the first code snippet is just to use: amount_t<NUM_OF_RECURSIONS>.times([](){}); |
Beta Was this translation helpful? Give feedback.
-
int main()
{
mlib::get_nth_element<N>(42, 'c', 3.14, true); // will return the Nth element of the args passed in.
mlib::get_nth_element<2>(42, 'c', 3.14, true); // returns 3.14
} This will be useful because 1. It is very fast, is doesn't use recursion it instead just uses the tequnice Imeadiatley Invoked Lambdas. It is relatively simple, and it very easy to use pass the element you want to find, The function namespace mlib {
template <auto N> constexpr auto get_nth_element(auto... args) {
return [&]<std::size_t... Indexes>(std::index_sequence<Indexes...>) {
return [](decltype((void *)Indexes)... DontCare, auto *arg,
auto *...DontCareEither) { return *arg; }(&args...);
}(std::make_index_sequence<N>{});
}
} // namespace mlib |
Beta Was this translation helpful? Give feedback.
-
struct s {
static constexpr auto x = inline_if<char, SameAs, bool, 42, 'c'>{}();
};
int main() { std::cout << s{}.x; } Note that namespace mlib
{
struct SameAs {};
// this is a bad implementation, becuase it requires operator==
template <typename A, typename B> struct is_same {
static constexpr bool value = false;
};
template <typename A, typename B>
requires(A{} == B{})
struct is_same<A, B> {
static constexpr bool value = true;
};
template <typename T, typename condition, typename ToCompare, auto first_,
auto second_>
struct inline_if {
constexpr inline_if() {}
constexpr auto get() {
}
constexpr auto operator()() { return get(); }
static constexpr auto first = first_;
static constexpr auto second = second_;
};
template<typename condition, typename ToCompare, auto first_, auto second_>
struct inline_if<is_same, condition, ToCompare, first_, second_>
{
constexpr inline_if() {}
constexpr auto get() {
if constexpr (is_same<T, ToCompare>::value) {
return first;
} else if constexpr (!is_same<T, ToCompare>::value) {
return second;
}
constexpr auto operator()() { return get(); }
static constexpr auto first = first_;
static constexpr auto second = second_;
};
} // namespace mlib So, it is very to use, just providing 5 template parameters, initializing the object: |
Beta Was this translation helpful? Give feedback.
-
template <auto... Ts> auto function(mlib::value_pack<Ts...> &pack_) {
return pack_.begin();
}
template <auto... Ts> auto function_two(mlib::value_pack<Ts...> pack_) {
static_assert(pack_.size() > 3);
return pack_[mlib::index<2>{}];
}
int main() {
std::cout << function_two(mlib::value_pack<'c', true, 42, 3.142>{});
} It is just a wrapper around a pack, which allows things to do with parameter packs, template<auto... Ts>
static constexpr mlib::value_pack<Ts...> v_p = mlib::value_pack<Ts...>{}; So then it would all be really easy to use. The implementation looks as follows: godbolt: // pack.hpp
#include <cstddef>
#include <iostream>
#include <utility>
#include"get_nth_element.hpp"
namespace mlib {
template <auto I> struct index {};
template <auto... Ts> struct value_pack {
static constexpr auto begin_value = mlib::get_nth_element<0>(Ts...);
static constexpr auto end_value =
mlib::get_nth_element<sizeof...(Ts) - 1>(Ts...);
static constexpr auto size_value = sizeof...(Ts) - 1;
constexpr auto size() { return (sizeof(Ts) + ... + 0); }
constexpr auto begin() { return begin_value; }
constexpr auto end() { return end_value; };
template <auto I> constexpr auto operator[](index<I>) {
return mlib::get_nth_element<I>(Ts...);
}
template <auto I> constexpr auto get() {
return mlib::get_nth_element<I>(Ts...);
}
value_pack() { /*Does Nothing!*/}
};
} // namespace mlib So, it is very simple to use, just pass in your parameter pack and then use it like an object! |
Beta Was this translation helpful? Give feedback.
-
namespace mlib
{
template <typename T, T I> struct integral_constant {
static constexpr T value = I;
using value_type = T;
constexpr operator value_type() const noexcept { return value; }
constexpr auto operator()() const noexcept { return value; }
};
} // namespace mlib |
Beta Was this translation helpful? Give feedback.
-
To add a new thing, first
float
the idea here, with an explanation on why it should be here!🎉: Will get put in the
mlib
library!💕: Has been put in, great feature!
👍: Looking Good!
🚀: Being put in now!
👎: No sorry, I don't think it would be suitable.
Beta Was this translation helpful? Give feedback.
All reactions