#xieite
1947 messages · Page 2 of 2 (latest)
So the preprocessor can treat them differently
hm
I'm not sure if this is doable with templates alone. I used PP to split the args into strings and non-strings
why not just make the preprocessor treat every other argument differently?
Eh. It can start with a variable
You could have two variables in a row
But that's an interesting idea 
ok i think i've thought of a way to fix my function
@pearl cliff your branch is 999 commits out of date btw
I'll catch up eventually
hehehe
I am making news aggregator this website provides specifically news from a single source for UPSC aspirants I am using the mern stack, if someone can talk to me for a while it will be appreciated.
please use a different channel
xieite has that feature builtin
XIETE_MAKE_NEWS_AGGREGATOR macro
@late ore i implemented your suggestion
Which one?
the "allowing { and } in the delimiter for xieite::dump" one
this
xieite::dump<"{}">(1, 2, 3);
```will now print```
1{}2{}3
Ahhh
it took all day
and i separated the formatting and printing stuff for xieite::dump
nice

i want to maybe make a post on reddit
to showcase the library and ask for feedback/suggestions
what should i write?
Dump? This is an intercalation
wdym
he means the name is misleading
like dump and intercalation is combined into one
but it looks fine to me 
well it started as an implementation of https://wg21.link/p2879
i just extended it
intercalate (in haskell) is a generalization of intersperse - you intersperse some list with another list instead of a single element. Strings are listy
Lol isn't that the AI slop/"the ub question" bloke
is it?
123
{}{}{}
1{}2{}3{}
well i liked the idea
seems pretty useless to me, just use cout at that point
sometimes i want to print a value or a couple values and i don't want to write a format string
that's all there is to it
You don't need to write format strings for streams
surely you can see the usecase ```cpp
std::println("{} {} {} {}", a, b, c, d);
streams are gross
¯_(ツ)_/¯
hah
ig u can have a separate helper function for intercalation, or “joining”
std::FILE* operator<<(std::FILE* f, auto&& x) {
std::print(f, "{}", x);
return f;
}
stdout << 1 << ' ' << 2 << ' ' << 3;
oh god i hate it
yup, that's xieite::fmt_join<>
ok
should i rename it to intercalate?
Fwiw this entire functionality becomes utterly pointless as soon as we get proper reification or interpolated string literals (what python calls fstrings)
TRUE
is it always a template parameter?
wdym
interpolated strings would be awesome
It shouldn't need to have to, but that creates an ambiguity on the first arg
can i join two dynamic strinngs with ur library
fmt_join(“,”, 1, 2, 3)
That shouldn't work. One of the arguments has to be of class type
ah ok
ah, sorry, it does something different
not when the delimiter is required
you'd use it like ```cpp
template<xieite::fixed_str delim, typename... Args>
std::string join(Args&&... args) {
return std::format(xieite::fmt_join<delim, Args...>, XIEITE_FWD(args)...);
}
like pythons .join
Yes, but that reads badly
actually i should just add that to the library as well
Fwiw just use std::views::join
yeah sure
wait, no, that requires a range
args aren't always the same type
After stringization they are
hmm
should i name this intercalate?
intercalate<"+">(1, 2.0, "3") // "1+2+3"
Depends on what you want to express
why though
what if the delimiter is unknown
Intercalate is a generalization of intersperse - it works with lists. I would expect intercalate to intercalate with any list, not just strings
compile time
std::ranges::range could be used instead maybe
Or just call it join if you do string stuff
maybe
i see
join isn't descriptive enough
i agree cause it sounds similar to append in functionality
what is intersperse?
The same as intercalate but inserting a scalar instead of the contents of a list
scalar as in the C++ definition of scalar or something else?
As in a single element
it exists now
.
;compile gsnapshot -std=c++26 -include/opt/compiler-explorer/libs/xieite/main/include/xieite/io/dump.hpp ```cpp
xieite::dump<"{}">(1, 2, 3);
1{}2{}3
works :)
dump is really quite an unfitting name tbf
what would you call it?
also it's just based on the proposal i linked earlier
so i called it the same as that
but that doesn't at all mention anything related to printing
intercalate_str
uhhhh
it defaults to a space
;compile gsnapshot -std=c++26 -include/opt/compiler-explorer/libs/xieite/main/include/xieite/data/intersperse.hpp ```cpp
std::println("{}", xieite::intersperse<"+">(1, 2, 3));
anyway i added this
1+2+3
intersperse is still a better name
anything formattable
;compile gsnapshot -std=c++26 -include/opt/compiler-explorer/libs/xieite/main/include/xieite/data/intersperse.hpp ```cpp
std::println("{}", xieite::intersperse<"qwertyuioplkjhgfdsazxcvbnm">(1, 2, 3));
1qwertyuioplkjhgfdsazxcvbnm2qwertyuioplkjhgfdsazxcvbnm3
its funny that its a template parameter
why?
because it couldve been a normal function argument of course
that would be harder to make
it's easier to put the delimiter directly into the format string
std::print always does that haha
improved the thingamabob
https://godbolt.org/z/qsEqK811r
the old implementation was worse
man I don't even know what the old implementation was 
good
what is this even good for though
visualizing numbers
std::unordered_map<std::string, std::vector<std::pair<std::string, std::string>>> something() {
decltype(return) result{};
…
return result;
}
To think of it, you can probably pull this off with stateful templates my beloved 
return {};
template<xieite::end..., typename Return = /* ... */>
Return something() {
Return result {};
return result;
}
@late ore ^
wdym
??
decltype(something())
but dexltype(return) is more fun 
would require passing all the args too
;compile clang_trunk -Wno-undefined-internal -std=c++26
template <typename Key>
struct Reader
{
friend auto foo(Reader<Key>);
};
template <typename Key, typename Value>
struct Writer
{
friend auto foo(Reader<Key>) {return Value{};}
};
template <typename Key>
struct AutoWriter
{
template <typename T, typename = decltype(void(Writer<Key, T>{}))> operator T();
};
#define GUESS_RET_TYPE \
using ReturnKey = decltype([]{}); \
if (false) \
return AutoWriter<ReturnKey>{}; \
using ReturnType = decltype(foo(Reader<ReturnKey>{}));
// ---
int blah()
{
GUESS_RET_TYPE
ReturnType ret = 42;
return ret;
}
int main() {}
yeah

my solution is the simplest
Yes, but where's the fun in that?!
R(Ts…)
@fringe beacon just wondering in your library do you have a way to iterate over a std::tuple
std::apply
~~well that's not in the xieite namespace
~~
thanks tho, forgot that existed 
with xieite you could do a similar thing if you wanted
auto tuple = std::make_tuple(1, 2.0, '3');
xieite::repeat<3>([&]<std::size_t i> {
std::println("{}", std::get<i>(tuple));
});
as opposed to making a fold expression with std::apply
i really need tests
i really need tests
test in production
Are you gonna write your own testing library first? 😛
static_asserts are enough i think
and then a bash script to run all the tests :P
just commit to it and spend a few days (or a week) on the tests. you will be very happy
i sure was when i buffed up my compiler's tests
hmm okay
@fringe beacon Do you use a ruler in your text editor?
I'm looking at this code, for example, and I feel like it's too wide. ```cpp
namespace xieite {
template<std::ranges::forward_range Range, std::ranges::forward_range Subrange, xieite::is_invoc<bool(std::ranges::range_common_reference_t<Range>, std::ranges::range_common_reference_t<Subrange>)> Pred = std::ranges::equal_to>
[[nodiscard]] constexpr auto after(Range&& range, Subrange&& subrange, Pred&& pred = {})
noexcept(xieite::is_noex_range<Range> && xieite::is_noex_range<Subrange> && xieite::is_noex_invoc<Pred, bool(std::ranges::range_common_reference_t<Range>, std::ranges::range_common_reference_t<Subrange>)>) {
return std::ranges::subrange(std::ranges::search(range, subrange, XIEITE_FWD(pred)).end(), std::ranges::end(range));
}
template<std::ranges::input_range Range>
[[nodiscard]] constexpr auto after(Range&& range, std::ranges::range_common_reference_t<Range> x)
noexcept(xieite::is_noex_range<Range>) {
return std::ranges::subrange(std::ranges::next(std::ranges::find(range, x), 1, std::ranges::end(range)), std::ranges::end(range));
}
}
how would you format it?
i don't use a column limit
I made a pull request.
:O
i don't see any
i see this though
https://github.com/Eczbek/xieite/compare/main...Hurubon:xieite:patch-1
i'll have to see it from a desktop
I'm stupid, it should be up now.
There's a mistake in line 20.
Should be std::ranges::range_common_reference_t.
ok i'm at my computer now
an anonymous namespace doesn't do anything useful in a header
My bad, I didn't think of that.
I wasn't expecting to get the pull request accepted, I just wanted to try the feature out.
yeah thanks btw
Do you think this kind of change would make sense?
here's my attempt ```cpp
namespace xieite {
template<
std::ranges::forward_range Range,
std::ranges::forward_range Subrange,
xieite::is_invoc<bool(
std::ranges::range_common_reference_t<Range>,
std::ranges::range_common_reference_t<Subrange>
)> Pred = std::ranges::equal_to
> [[nodiscard]] constexpr auto after(
Range&& range,
Subrange&& subrange,
Pred&& pred = {}
) noexcept(
xieite::is_noex_range<Range>
&& xieite::is_noex_range<Subrange>
&& xieite::is_noex_invoc<Pred, bool(
std::ranges::range_common_reference_t<Range>,
std::ranges::range_common_reference_t<Subrange>
)>
) {
return std::ranges::rubrange(
std::ranges::search(
range,
subrange,
XIEITE_FWD(pred)
).end(),
std::ranges::end(range)
);
}
template<std::ranges::input_range Range>
[[nodiscard]] constexpr auto after(
Range&& range,
std::ranges::range_common_reference_t<Range> x
) noexcept(xieite::is_noex_range<Range>) {
return std::ranges::subrange(
std::ranges::next(
std::ranges::find(range, x),
1,
std::ranges::end(range)
),
std::ranges::end(range)
);
}
}
though i might've gone too far
I wanted to submit something like this, but I thought it might've been too extreme.
I didn't know if you have some sort of style guide or format.
kind of, but it isn't written down and also i decide to break it sometimes
generally, YES
but actually doing this would be difficult
finding a good format for everything
Okay, I'll get on this when I get tired of Silksong.
What is the change?
first of all, tests
which may lead to some changes in areas i overlooked earlier
(writing tests will force me to look at everything)
then i want to add a few data structures and simplify most of the string and ranges code
if it works out
Is this something that is almost done or is there a planned ETA?
no i haven't started :)
Hm. So why can't I get started on this?
i guess there's no reason not to, after all

it's genius
@fringe beacon I think quote in quote.hpp is bugged.
return (delim == esc) // What is this? vvvvv
? (delim + xieite::str_replace(str, delim, String(1, esc, alloc) + delim, alloc) + delim, alloc)
: (delim + xieite::str_replace(xieite::str_replace(str, esc, Str(2, esc, alloc), alloc), delim, Str(1, esc, alloc) + delim, alloc) + delim);
yup that is a typo
i guess , alloc should not be there
thanks
doesn't work because preprocessor funkiness with whitespace
maybe i should use just a tad less preprocessor
Write your own
@fringe beacon In str_join, why do pfx and sfx use std::type_identity_t?
to avoid type deduction for those parameters
instead they'll be converted to the first type
You should add a xieite::avoid_deduction.
that's pretty lengthy
how about obstruct?
dont_deduce?
undeduce :P
@fringe beacon I don't know if you're aware, but you have a few pull requests open.
oh thanks
oh gosh
you know you could probably put all of these in a single PR
that or make some kind of clang-tidy thingamabob that formats it automatically
I didn't think that was a good idea.
why not?
I made different kinds of changes. If you don't like some of them, you can just merge what you want.
hmm
that's probably a feature yes
thoughts on these names? ```cpp
unfold<5>([]<int... i> { // called once
(..., std::println("{}", i));
});
unroll<5>([]<int i> { // called 5 times
std::println("{}", i);
});
why cant you just call std:println normally without a wrapper function
println is there just for the example
they make sense to me so
It took me about a minute of thinking to understand, but the names make sense.
thanks!
After some more thought, I feel like unfold might be problematic.
why?
To me, unfolding doesn't imply any kind of repetition.
What is the motivation behind these abstractions?
Can you show a side by side comparisson?
[]<std::size_t... i>(std::index_sequence<i...>) {
(..., std::println("{}", i));
}(std::make_index_sequence<5>());
// vs
unfold<5>([]<std::size_t... i> {
(..., std::println("{}", i));
});
Is being neat paramount?
merely a preference
also, 5 comes first rather than last in the entire expression
I prefer clarity over neatness. I feel like option 1 is clearer.
maybe, but i use this quite frequently (so less repetition is better, i think)
That's an interesting point.
Do you have any examples from your code?
could you impl unroll but instead of a int its a tuple
a tuple of integers?
it uses std::make_index_sequence internally so it has to be integers
but you could transform those?
how would this work?
what kinds of tuples would be generated automatically?
?
I mean you could get<N> it anyways ig
i'm not sure what you mean with your suggestion about tuples
can you write an example
nvm
but basically I was talking about like
unroll(tuple, [](auto&& i) { // the num is deduced to std::tuple_size_v<tuple>, and then rolled over using std::get
std::println("{}", i);
});
sounds like std::apply
What am I looking at?
some neat code
joking here it is before preprocessing
not sure how to format the middle line
inline constexpr auto pipe = [][[nodiscard]](auto&& value, auto&&... funcs) XTE_ARROW(
xte::unfold<(sizeof...(funcs) - !!sizeof...(funcs))>([]<xte::uz... i>(auto&& value, auto&&... funcs) XTE_ARROW(
xte::arg_at<(sizeof...(funcs) - !!sizeof...(funcs))>(XTE_FWD(funcs)..., xte::identity)(XTE_FWD((DETAIL_XTE::pipe::wrap_value(XTE_FWD(value))->*...->*DETAIL_XTE::pipe::wrap_func(xte::arg_at<i>(XTE_FWD(funcs)...))).value))
), XTE_FWD(value), XTE_FWD(funcs)...)
);
@hidden tulip lambdas
i'm not even trying to read that
actually, meh, i'm bored, will give it a try
what is XTE_ARROW tho?
#define ARROW(...) \
noexcept(noexcept(__VA_ARGS__)) \
-> decltype(auto) \
requires(requires { __VA_ARGS__; }) \
{ return __VA_ARGS__; }
the requires there is to validate the expression produced by the given arguments?
yes
i don't think that's very useful here tho, but alright, whatever
perhaps not for functions with just 1 overload
this whole thing allows me to write ```cpp
template<typename T>
constexpr auto fwd_like = [][[nodiscard]](auto&& x) noexcept -> auto&& {
return xte::pipe(
XTE_FWD(x),
xte::value_at<xte::is_c<T>, xte::as_not_c, xte::as_c>,
xte::value_at<xte::is_v<T>, xte::as_not_v, xte::as_v>,
xte::value_at<xte::is_lref<T>, xte::move, xte::unmove>
);
};
I stare at pipes all day at work and then I come home to xte::pipe.
my guess is that unfold is just feeding value and funcs and i (as an index_sequence), and then arg_at just executes the forwarded value (assuming it's the result of the prior call), and then it builds the chain of functions paired with i as that specific index, to have some sort of sorted map where each index points to its corresponding function, and then gets the final .value resulting from that internal execution of the sorted map of indices and functions (and forwarding the value all over as the input argument, that's probably the job of that wrap_value)
yea, looked very repetitive
it's much simpler than that
interesting 
i might take a look at it tomorrow
im working on other bugs rn 
some issues with dropped const qualifier on the pack
similar?
just realized it sounded like i was working on the bug you submitted from my message.
nope, im working on some ICEs
i have 3 crashes im fixing. but i might look at that one u submitted out of curiosity later
@sweet apex looks like Marek self-assigned the bug
very nice then
thank you
submit them all at the same time >:)
just fixing some simpler ICEs
getting used to gcc codebase
ill move onto to harder bugs in a bit once i finish these
oh by the way, i was trying to figure out this one earlier:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121900
might you have an estimate for how difficult this is?
thanks to the support of the gcc team im getting used to it quickly (its very nice to have help!)
i got stuck because i don't know how gcc works
WHERE
wait holdup
lucky
@fringe beacon is decltype(return) in xieite yet
ARROW
You can do that with stateful metaprogramming me thinks
i need to make a stateful type list
WHY WOULDN'T I BE?
WHY THE CAPS?!?!?!?!
I DONT KNOW EITHER
theres only 1 right answer
yes
std::add_const_t<std::add_volatile_t<T>>
classic
or just add_cv but i will silently ignore it
They're cv qualifiers, not vc qualifiers, qualifiers cv, qualifiers vc, c qualifiers v, or v qualifiers c.
but i write more "important" qualifiers first
and since volatile is rare, surely it should go before const which is much more common
important qualifiers write first more but I
the last two options are just for @\volatile
not the same 
write qualifiers important more i but
write
qualifiers
important
more
i
but
what am i even doing
I'm glad we're on the same page 🙂
glad on page same the we're I'm
lol
this is how i speak now
speak this now how is i
hey this is approaching yoda-speak
btw i have an idea
tell me if it's terrible
representing types as a base type + array of cv qualifiers + ref qualifier
because if you think about it, cpp int const* volatile* const volatile** const& is an array of const or volatile, and * is the delimiter like a comma
so then obviously i should be able to do range operations on this
add const to all elements between indices 1 and 3
erase index 2?
etc
i laughed hard at this
i had a similar idea for packing type info
do you have any ideas on how to handle function types?
or, should that be separate?
how did you split it up?
i didnt have multiple function types so it was just an array of [Ret, Args...]
ah
@wet holly i have about this much implemented ```cpp
using A = traits<int>;
using B = A::add_ptr<0, 3>; // traits<int***>
using C = B::add_c<1, 2>; // traits<int* const* const*>
using D = C::copy_ref<float&&> // traits<int* const* const*&&>
using E = D::type<> // int* const* const*&&
and a few more similar ones
also all function type qualifier things (add/remove/copy const/volatile/lref/rref/noexcept/varargs)
Hopefully some of my pull requests will be closed soon.
cppdecl::Type t = cppdecl::Type::FromSingleWord("int");
t.AddModifier(cppdecl::Pointer{});
t.AddModifier(cppdecl::Pointer{});
t.AddModifier(cppdecl::Pointer{});
t.AddQualifiers(cppdecl::CvQualifiers::const_, 1);
t.AddQualifiers(cppdecl::CvQualifiers::const_, 2);
t.AddModifier(cppdecl::Reference{.kind = cppdecl::RefQualifier::rvalue});
std::cout << cppdecl::ToCode(t, {}) << '\n'; // int *const *const *&&

this looks cool
yes
working on readability
hmm nice
very wordy though
how does FromSingleWord work?
It just asserts that it's an identifier
You can't make an actual type from the resulting object
aw
#include <cstring>
#include <string_view>
template <size_t N>
struct c_string{
char string[N];
};
template<std::size_t N>
c_string( const char(&)[N] ) -> c_string<N>;
template <c_string text>
using type_from_one_word = decltype([]() consteval
{
constexpr std::string_view work_with{text.string};
if constexpr(work_with == "int")
{
return int{};
}
else if constexpr(work_with == "double")
{
return double{};
}
}());
int main()
{
type_from_one_word<{"int"}> value;
type_from_one_word<{"double"}> value2 ;
static_assert(std::same_as<decltype(value), int>);
static_assert(!std::same_as<decltype(value), double>);
static_assert(!std::same_as<decltype(value2), int>);
static_assert(std::same_as<decltype(value2), double>);
}
let me cook
it not usable at runtime, but it works :/
Yeah. I mean I know it's possible, but it's not something I tried with my lib
Hardcoding the list of types is uncool
do you prefer ```c
if defined(A) \
|| defined(B)
define C
orc
if defined(A) \
|| defined(B)
define C
# if defined(A) \
|| defined(B)
# define C
```?
ew but maybe later
Former.
thanks, why?
I like how it's lined up vertically.
I like || at the end of the first line more 
# if defined(A) || \
defined(B)
# define C
```?
a bit yeah
first one
thanks!
someone pls format this i need inspiration ```cpp
inline constexpr auto exchange = []<xte::is_implicit_move_ctor T, xte::is_assignable_to<T&> U = T>[[nodiscard]](T& lhs, U&& rhs) noexcept(xte::is_noex_implicit_move_ctor<T> && xte::is_noex_assignable<T&, U>) -> T {
T old = xte::move(lhs);
lhs = XTE_FWD(rhs);
return old;
};
unironically the only way to make this readable is something like this
inline constexpr auto exchange = []<xte::is_implicit_move_ctor T, xte::is_assignable_to<T&> U = T>
[[nodiscard]] (T & lhs, U&& rhs) noexcept(xte::is_noex_implicit_move_ctor<T>
&& xte::is_noex_assignable<T&, U>) -> T {
T old = xte::move(lhs);
lhs = XTE_FWD(rhs);
return old;
};
or this
inline constexpr auto exchange = []<xte::is_implicit_move_ctor T, xte::is_assignable_to<T&> U = T>
[[nodiscard]] (T & lhs, U&& rhs)
noexcept(xte::is_noex_implicit_move_ctor<T>
&& xte::is_noex_assignable<T&, U>) -> T {
T old = xte::move(lhs);
lhs = XTE_FWD(rhs);
return old;
};
wait did discord ruin it
bruh
ill send a picture
since this is terrible cursed code there isnt many ways to make it readable
my best attempt is basically the same ```cpp
inline constexpr auto exchange =
[]<xte::is_implicit_move_ctor T, xte::is_assignable_to<T&> U = T>
[[nodiscard]](T& lhs, U&& rhs)
noexcept(xte::is_noex_implicit_move_ctor<T> && xte::is_noex_assignable<T&, U>)
-> T {
T old = xte::move(lhs);
lhs = XTE_FWD(rhs);
return old;
};
also works if you dont dislike the newline after the assignment
actually why am i requiring an implicit ctor
i could easily T old = T(xte::move(lhs));
@eternal ridge format this code please
Here’s your code formatted for better readability while keeping the modern C++ style intact:
inline constexpr auto exchange =
[]<xte::is_implicit_move_ctor T, xte::is_assignable_to<T&> U = T>
[[nodiscard]](T& lhs, U&& rhs)
noexcept(xte::is_noex_implicit_move_ctor<T> && xte::is_noex_assignable<T&, U>) -> T
{
T old = xte::move(lhs);
lhs = XTE_FWD(rhs);
return old;
};
I aligned the template parameters, the lambda signature, and the body so it’s easier to parse visually.
If you want, I can also give a more compact single-line version that’s still readable for modern C++ headers. Do you want me to do that?

XIEITE is a header-only C++ utility library providing cross-platform abstractions, compile-time metaprogramming tools, mathematical utilities, and system-level interfaces. The library prioritizes port
get rekt
i was staring at it, and not see difference for 5 min
Bro is literally ChatGPT 😭
zengpt
Hi, I’m ZenGTP, here to help out on anything you’re curious about. Anything on your mind?
can you add examples to the generated docs please
at least one example for every component
that will be quite the undertaking, in my current state I am unable to complete the given task. Let’s switch gears and dive into another topic. Would you like for me to give 1 or 2 examples in the chat?
smh
.
9
14
2
const volatile T
hah
template<typename T, std::size_t n>
struct fixed_array {
T _data[n];
// ...
};
template<typename... Ts>
fixed_array(Ts...) -> fixed_array<std::common_type_t<Ts...>, sizeof...(Ts)>;
``` is this a reasonable deduction guide?
it should fail anyway
do you prefer cpp auto add(auto x, auto y) ARROW(x + y) or```cpp
auto add(auto x, auto y) ARROW(
x + y
)
what even is this tho
ARROW?
sure
i have much practice at writing its definition
#define ARROW(...) \
noexcept(noexcept(__VA_ARGS__)) \
-> decltype(auto) \
requires(requires { __VA_ARGS__; }) \
{ return __VA_ARGS__; }
i prefer if arrow lets me type {}
skill issue
lol
ARROW(auto{...}) 
First
thanks
+1
it doesn't always work though
one sec i'll get an example where i prefer the second option
I think I like second more
it's smart and elegant
ikr
one thing that bugs me about it is if i have two functions nearby like this ```cpp
void foo(auto f) noexcept {
f();
}
auto bar(auto f) ARROW(
f()
)
Why not just have both of them be arrows?
void foo(auto f) noexcept
{
f();
}
auto bar(auto f) ARROW(
f()
)
Or
auto bar(auto f) ARROW(f())
hah
okay
ARROW still breaks compilers occasionally
What is that skull
ita a skull
It looks like the Android skull wo the teeth
indeed that is what is is
;compile -std=c++23```cpp
#define ARROW(...)
noexcept(noexcept(auto (VA_ARGS)))
-> decltype(auto)
requires(requires {auto (VA_ARGS); })
{ return auto (VA_ARGS); }
auto add(auto x, auto y)
ARROW({x + y})
<source>:8:16: warning: '__VA_ARGS__' can only appear in the expansion of a C++11 variadic macro
8 | { return auto (__VA_ARGS__);
| ^
<source>:7:2: error: expected unqualified-id before ')' token
7 | }) \
| ^
<source>:14:1: error: expected primary-expression before 'return'
14 | return 0;
| ^~~~~~
<source>:15:2: error: expected ')' at end of input
15 | }
| ^
| )
<source>:6:9: note: to match this '('
6 | requires(requires {auto (__VA_ARGS__);
| ^
<source>:12:1: note: in expansion of macro 'ARROW'
12 | ARROW({x + y})
| ^~~~~
<source>:15:2: error: expected initializer at end of input
15 | }
| ^
Build failed
;asm -std=c++23
No assembly generated.
you can't return references with this though
gulp
A musical parody of Don McLean's "American Pie" about the history of programming and software development.
remembered this after you said this
he released a new one recently btw
You ever found yourself trying to do something really simple, like show a username on a web page, but you can't because there's too much "architecture"? This one is for you.
Music: "Somebody Told Me" by The Killers.
Written by Brandon Flowers, Dave Keuning, Mark Stoermer, Ronnie Vannuci Jr. Copyright © 2004 The Killers Publishing / Lizard Kin...
I think I'm going to push what I have and then complete tests and docs later
But also a lot of things are still missing entirely
need LICENSE and a lot more in the readme
I deleted the license by accident, it will be back
the readme will also link to the docs when I do any of them
license fixed
can you re link, on phone it seems impossible to scroll to the top
C++ utility library. Contribute to Eczbek/xieite development by creating an account on GitHub.

for doc/readme maybe some sort of auto generated doxygen would help see what's available/discover it
Yeah definitely
I'll work on docs now
;compile gsnapshot -std=c++26 -freflection -I/opt/compiler-explorer/libs/xieite/main/include ```cpp
#include <xte/io/logger.hpp>
int main() {
xte::logger::info("Hello, world!");
}
INFO [2026-02-14 00:28:41] /app/example.cpp:int main():4: Hello, world!
splendid
hmm how do you get ur own files in godbolt?
hacks
(I asked mr godbolt nicely)
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/literal/analog.hpp ```cpp
using namespace xte::literal::analog;
std::println("{}", (x - - - +
!* *
! * *
! * *
+ + - - - +
* ! !
* ! !
*! !
+ - - - x).volume);
27
shouldn't it be 64 ?
it's 3x3x3
hmm no it's 4x4x4
how would you describe a 1x1x1 cube?
well for anything 2 or bigger it's pretty clear...
not that I get what this is useful for 🙂
haha
so how do you get files uploaded? you know the team personally ?
oh, I submitted a PR so that my library gets pulled every day
docs are about halfway done
at least of the things that are easy to update
which isn't a lot
is https://xieite.github.io/ still being used or did you switch to something else?
yup, still using that
I will push soon
nice
doesn't help
what url does it take you to when you click on the func category
some sort of cache happening, I renamed fn to func
Yeah I haven't rewritten that function yet
so your sidebar is wrong for some reason
try opening the docs in a private tab?
possibly
The sidebar is designed horribly currently
it's just an embed of another page
:P

I don't know fancy HTML tricks
\:P
or just disable it in discord settings
idk it works so maybe i'll touch it later
https://xieite.github.io/func/visitor
two sidebars!
now make four 
now just add an ai chatbot and your 99% the way there to becoming a startup
haha
I made it work on mobile just so that I could look up the docs when I wasn't at my computer
alright I updated more of the docs
All of the ones listed on the left should be good
feels good to be working on this again

If I see an autogenerated doxygen as docs I'm not even reading them, they are already in the code
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/preproc/lambda.hpp ```cpp
auto f = XTE_LAMBDA($0 + 1);
std::println("{}", f(1));
auto g = XTE_LAMBDA_LOCAL(f($0 + $1));
std::println("{}", g(2, 3));
2
6
@night abyss it works now
how does $n syntax even work
;asm -E -P -include/opt/compiler-explorer/libs/xieite/main/include/xte/preproc/lambda.hpp
auto f = XTE_LAMBDA($0 + 1);
auto f = ([]<decltype(auto)... $$ >[[nodiscard]]( [[maybe_unused]] auto&&... $) static noexcept (requires ( decltype($)&&... $) { requires ([]( auto&&... $) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
return ([&]<decltype(auto) $$0, decltype(auto) $$1, decltype(auto) $$2, decltype(auto) $$3, decltype(auto) $$4, decltype(auto) $$5, decltype(auto) $$6, decltype(auto) $$7, decltype(auto) $$8, decltype(auto) $$9, decltype(auto) $$A, decltype(auto) $$B, decltype(auto) $$C, decltype(auto) $$D, decltype(auto) $$E, decltype(auto) $$F, decltype(auto)...>(auto&& $0, auto&& $1, auto&& $2, auto&& $3, auto&& $4, auto&& $5, auto&& $6, auto&& $7, auto&& $8, auto&& $9, auto&& $A, auto&& $B, auto&& $C, auto&& $D, auto&& $E, auto&& $F, auto&&...) mutable -> decltype(auto) { return noexcept($0 + 1); }).template operator()<$$..., 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>(static_cast<decltype($)&&>($)..., 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
#pragma GCC diagnostic pop
})( static_cast<decltype($)&&>($)...); }) -> decltype(auto) requires (requires ( decltype($)&&... $) { requires ([]( auto&&... $) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
return ([&]<decltype(auto) $$0, decltype(auto) $$1, decltype(auto) $$2, decltype(auto) $$3, decltype(auto) $$4, decltype(auto) $$5, decltype(auto) $$6, decltype(auto) $$7, decltype(auto) $$8, decltype(auto) $$9, decltype(auto) $$A, decltype(auto) $$B, decltype(auto) $$C, decltype(auto) $$D, decltype(auto) $$E, decltype(auto) $$F, decltype(auto)...>(auto&& $0, auto&& $1, auto&& $2, auto&& $3, auto&& $4, auto&& $5, auto&& $6, auto&& $7, auto&& $8, auto&& $9, auto&& $A, auto&& $B, auto&& $C, auto&& $D, auto&& $E, auto&& $F, auto&&...) mutable -> decltype(auto) { return requires { $0 + 1; }; }).template operator()<$$..., 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>(static_cast<decltype($)&&>($)..., 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
#pragma GCC diagnostic pop
})( static_cast<decltype($)&&>($)...); }) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
return ([&]<decltype(auto) $$0, decltype(auto) $$1, decltype(auto) $$2, decltype(auto) $$3, decltype(auto) $$4, decltype(auto) $$5, decltype(auto) $$6, decltype(auto) $$7, decltype(auto) $$8, decltype(auto) $$9, decltype(auto) $$A, decltype(auto) $$B, decltype(auto) $$C, decltype(auto) $$D, decltype(auto) $$E, decltype(auto) $$F, decltype(auto)...>(auto&& $0, auto&& $1, auto&& $2, auto&& $3, auto&& $4, auto&& $5, auto&& $6, auto&& $7, auto&& $8, auto&& $9, auto&& $A, auto&& $B, auto&& $C, auto&& $D, auto&& $E, auto&& $F, auto&&...) mutable -> decltype(auto) { return $0 + 1; }).template operator()<$$..., 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>(static_cast<decltype($)&&>($)..., 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
#pragma GCC diagnostic pop
});
xd
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/data/string.hpp ```cpp
xte::string s;
s += "hello";
std::print("{}", s);
hello
string and array work
what are you cooking
shorthand lambda syntax
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/math/big_int.hpp ```cpp
std::println("{}", xte::big_int(99).pow(99));
00420006028460828220000240826646662822224844246624084240648422060028460824206802008020828642682646062242688642662204002048802060042266002000888268242240242880628040466848888468680220248288602433876430563566003089
great, I don't know what's wrong
oh the stringifier is broken
;compile ```js
console.log(99n**99n);
369729637649726772657187905628805440595668764281741102430259972423552570455277523421410650010128232727940978889548326540119429996769494359451621570193644014418071060667659301384999779999159200499899n
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/math/big_int.hpp ```cpp
std::println("{}", xte::big_int(99).pow(99) == xte::big_int("369729637649726772657187905628805440595668764281741102430259972423552570455277523421410650010128232727940978889548326540119429996769494359451621570193644014418071060667659301384999779999159200499899"));
true
How do you do the division for printing purpose? I remember that python had this loud thing about DOS by sending long ints that took forever to format using regular division xD
using regular division, it's very slow
hmm, maybe I could format (almost) entire long ints at a time
That's probably a better idea, than doing it by the digit. I wonder if divide and conquer (splitting roughly in half) might work well
would be good to research stringification techniques
we try again
;compile gsnapshot -std=c++26 -freflection -I/opt/compiler-explorer/libs/xieite/main/include ```cpp
#include <xte/math/big_int.hpp>
#include <print>
int main() {
std::println("{}", xte::big_int(99).pow(99));
}
00420006028460828220000240826646662822224844246624084240648422060028460824206802008020828642682646062242688642662204002048802060042266002000888268242240242880628040466848888468680220248288602433876430563566003089
oh, still some time before godbolt updates
WE TRY AGAIN
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/math/big_int.hpp -DA=A ```cpp
std::println("{}", xte::big_int(99).pow(99));
369729637649726772657187905628805440595668764281741102430259972423552570455277523421410650010128232727940978889548326540119429996769494359451621570193644014418071060667659301384999779999159200499899
there we go
;compile gsnapshot -std=c++26 -freflection -I/opt/compiler-explorer/libs/xieite/main/include ```cpp
#include <xte/io/file.hpp>
#include <xte/io/std.hpp>
int main() {
if (auto f = xte::file(FILE, xte::file::mode::read)) {
xte::std::out.write(f.read());
}
}
#include <xte/io/file.hpp>
#include <xte/io/std.hpp>
int main() {
if (auto f = xte::file(__FILE__, xte::file::mode::read)) {
xte::std::out.write(f.read());
}
}
i almost want to say something about 2**10 ~ 10**3, but i really don't know how it would help without being exact
something something logarithms
and then there's negative radices
I suppose it would be useful to optimize the case for radix=10 though
maybe operator overloading
what about operator overloading?
could do xte::big_int(99) ** 99_exp but I'm not sure it's worth it
is that possible?
yes
that's a binary operator* and a unary operator*
i see
which is why the _exp is needed
literals fix everything
yes :P
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/util/cast.hpp ```cpp
std::println("{}", xte::cast<int>(3.14159));
3
maybe create literal 1_B
boolean?
big int
oh
that makes sense
i tried find code in your xiete github, but there no big_int
;compile clang_trunk -std=c++23 -isystem /opt/compiler-explorer/libs/boost_1_80_0 ```cpp
#include <bits/stdc++.h>
#include <boost/multiprecision/cpp_int.hpp>
boost::multiprecision::cpp_int test("99");
std::cout << boost::multiprecision::pow(test, 99);
369729637649726772657187905628805440595668764281741102430259972423552570455277523421410650010128232727940978889548326540119429996769494359451621570193644014418071060667659301384999779999159200499899
nice
?
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/math/big_int.hpp ```cpp
using namespace xte::literal::big_int;
std::println("{}", 99_big .pow(99));
<source>: In function 'int main()':
<source>:5:20: error: call to consteval function 'xte::literal::big_int::operator""_big<'9', '9'>()' is not a constant expression
5 | std::println("{}", 99_big .pow(99));
| ^~~~~~
<source>:9:1: error: 'xte::literal::big_int::operator""_big<'9', '9'>()' is not a constant expression because it refers to a result of 'operator new'
9 | }
| ^
Build failed
thought I fixed that
;compile gsnapshot -std=c++26 -include/opt/compiler-explorer/libs/xieite/main/include/xte/preproc/version.hpp ```cpp
std::println("v{}.{}.{}", XTE_VERSION_MAJOR, XTE_VERSION_MINOR, XTE_VERSION_PATCH);
v0.155.2
it isn't a consteval function though
oh, it contains a call to a consteval function
took 3 hours to fix? yey
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/math/big_int.hpp -Ddummy=0 ```cpp
using namespace xte::literal::big_int;
std::println("{}", 99_big .pow(99));
369729637649726772657187905628805440595668764281741102430259972423552570455277523421410650010128232727940978889548326540119429996769494359451621570193644014418071060667659301384999779999159200499899
FINALLY
more docs https://xieite.github.io/meta/wrap_value
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/math/wrap.hpp ```cpp
for (int i = 0; i < 5; ++i) {
std::println("{}", xte::wrap(i, 2, -1));
}
0
1
-1
0
1
2 should be inclusive hmm
I feel it's fine being exclusive tbh makes sense
maybe. I made it inclusive though.
We'll see if it makes sense later on
i feel like wrap can be inclusive honestly, its more intuitive
you can also add wrap_exclusive or something
it has been an absolute pain to get working properly
and I'm still working on it
the one on github is borked
lol, i dont wanna find out what your impl looks like
it's pretty simple
i should probs make a showcase for my new compiler
you should!
lol no. its for a stack based language me and my PL theory friend came up with
it will probs have C FFI eventually among other things
its a big project for me to implement a full compiler stack from frontend to backend with real world optimizations found in gcc and llvm
aw
i could probs make a C frontend in like a month or less that targets my middle end
its something to consider later once it has enough optimizations to be worth benchmarking against llvm and gcc
its already nice that it has some opts going on
that is cool
i only spent a few hundred hours of my time on it so it still has a long way to go
I thought this was godbolt.org for a sec 😵💫
mobile view for godbolt
so it like your godbolt?
what does that mean
like that your wrapper for godbolt for mobile?
yes
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/math/wrap.hpp ```cpp
for (int i = -5; i <= 5; ++i) {
std::print("{} ", xte::wrap(i, 1, -1));
}
1 -1 0 1 -1 0 1 -1 0 1 -1
nice
also does it matter if its wrap(i, -1, 1) vs wrap(i, 1, -1)?
nope!
either way works
;compile gsnapshot -std=c++26 -freflection -I/opt/compiler-explorer/libs/xieite/main/include```cpp
#include <print>
#include <xte/literal/numbers.hpp>
using namespace xte::literal::numbers;
int main() {
std::println("{:X}", 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u128);
}
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
oh also
;compile gsnapshot -std=c++26 -freflection -I/opt/compiler-explorer/libs/xieite/main/include```cpp
#include <print>
#include <xte/literal/numbers.hpp>
using namespace xte::literal::numbers;
int main() {
std::println("{}", 5_b);
}
true
just because
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/math/div_ceil.hpp ```cpp
std::println("{}", xte::div_ceil(5, 2));
3
a few division rounding functions
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/math/div_floor.hpp ```cpp
std::println("{}", xte::div_floor(-5, 2));
-3
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/math/avg.hpp ```cpp
std::println("{}", xte::avg(1, 2, 3));
2
avg here uses only integers and probably cannot overflow
You should try adding these as "traits" (ie abstract bases) and concepts so that users can overload to their own type
And then we can recreate rust generics 
can you make an example please?
I'm on my phone rn but I'm pretty sure someone got something close to rust traits on cppcon
Then again it might be slideware but you can check
slideware haha
what exactly is this library
useful and interesting things
sometimes both
oh btw apparently there was another bug in xte::stringify_number() caused by rounding errors but that is fixed now
do you have tests?
oh u do im dumb
This time, yes!
smh why aren't we using xte::logger::info()
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/io/logger.hpp -include/opt/compiler-explorer/libs/xieite/main/include/xte/math/avg.hpp ```cpp
xte::logger::info("{}", xte::avg(1, 2, 3));
INFO [2026-05-01 00:47:18] /app/example.cpp:int main():3: 2
there we go
neat
something else I just fixed (but godbolt won't update for another 23 hours) is xte::init_list<> for multidimensional arrays
xte::array<xte::array<int>> array = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};
everything here is std::moved, not copied :)
previously it just errored if you had an init list inside an init list
also btw what's that function you have which just allocates a really large array and checks if any bit flips
oh I haven't re-added that yet
it was detect_cosmic_ray() and it wouldn't return until it indeed detected a bit flip
well I'm going to need that ASAP otherwise my vibe-coded SaaS Fortune 100 company will go bankrupt
\s
Working on it as we speak
how does this interface look? ```cpp
xte::detect_cosmic_ray();
std::println("Cosmic ray detected!");
too complicated for my ai agents to understand
dumb down the api some more
gahhh
also this will be running on mars so it needs to have robust error handling
I have just the thing: ```sh
#!/usr/bin/env bash
while true; do
./program
done
upon any crash, it automatically restarts your program
perfect!
yayyyyyy
this page is finally done
https://xieite.github.io/data/array
removed all javascript from the docs now
is this use big_int?
or depends on deducing
template <typename T>
concept number = std::integral<T> || std::floating_point<T>;
[[nodiscard]] constexpr
auto avg(number auto... nums) -> std::common_type_t<decltype(nums)...> {
return ((nums + ...)) / sizeof...(nums);
}
nope
only the types that you pass it
well, it gets the common_type_t
that can overflow
true
mine doesn't overflow >:)
nope
it doesn't use larger types
so, what if it overflow?
oh wait
im stupid
it just cant
you do (num0 / size) + (num1 / size) for floats
em
can i do push request of just formatting 
but is the formatting good?
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/data/array.hpp ```cpp
xte::array<xte::array<int>> a = {
{ 1, 2, 3 },
{ 4, 5, 6 }
};
std::println("{}", a);
[[1, 2, 3], [4, 5, 6]]
2D arrays with convenient initializer
uhoh
all my code is 3 space indent
do you not have a .clang-format or something?
I format code manually :)
formatter formats my code weird
you could probably get clang-format or some other formatter to get it to your taste
// clang-format off
// your entire file goes here
// clang-format on
``` now you can use clang-format

How does this work? 
what about it?
Nvm I'm still sleepy
I thought you got std::array-like class to work with nested braces
without {{...}}
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/math/eval.hpp ```cpp
static_assert(xte::eval<int>("2 + 2 * 2") == 6);
someone opened an issue and it took me 5 days to notice
hm
;asm -E -P -include/opt/compiler-explorer/libs/xieite/main/include/xte/preproc/version.hpp ```cpp
XTE_VERSION_MAJOR.XTE_VERSION_MINOR.XTE_VERSION_PATCH
0 . 184 . 4
why hasn't it updated
;compile g161 -std=c++26 -freflection -I/opt/compiler-explorer/libs/xieite/main/include ```cpp
#include <xte/data/array.hpp>
#include <xte/data/init_list.hpp>
#include <xte/data/ptr.hpp>
#include <xte/util/xvalue.hpp>
template<typename T>
struct MyArray {
xte::array<T> data;
MyArray(xte::init_list<T> list) {
for (auto&& item : list) {
this->data.push(xte::xvalue(item));
}
}
};
int main() {
MyArray<xte::ptr<int>> a = {
xte::ptr<int>::make(5),
nullptr
};
}
Please don't cross-post the same message across multiple channels (#c-cpp-discussion, #1162965399684534313). Pick the most appropriate channel for your question and ask there.
ok wheatley
replaced a lot of static_casts with calls to xte::cast because that properly handles floating point shenanigans*
(hopefully)
what isn't?
the compiling random files to discord i dont understand whyù
I don't know what you mean?
the compiler bot?
yes
why do you dislike it?
unpractical
for what?
what's the alternative?
because it's convenient when talking about code?
its not worth it!
unpractical a bad practice!
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/math/eval.hpp ```cpp
static_assert(xte::eval<int>("2 + 2 * 2") == 6);
In file included from /opt/compiler-explorer/libs/xieite/main/include/xte/math/../data/../data/../preproc/arrow.hpp:8,
from /opt/compiler-explorer/libs/xieite/main/include/xte/math/../data/../data/range_cmp.hpp:6,
from /opt/compiler-explorer/libs/xieite/main/include/xte/math/../data/array.hpp:4,
from /opt/compiler-explorer/libs/xieite/main/include/xte/math/eval.hpp:4,
from <command-line>:
/opt/compiler-explorer/libs/xieite/main/include/xte/math/../data/../data/../preproc/arrow.hpp:38:129: error: 'DETAIL_XTE_arg' was not declared in this scope; did you mean 'DETAIL_XTE_Arg'? [-Wtemplate-body]
38 | requires(requires { XTE_IF(XTE_ANY(_arg))(([](XTE_UNWRAP(_arg)) requires(requires { __VA_ARGS__; }) {})(XTE_FWD(DETAIL_XTE_arg)))(__VA_ARGS__); })) \
| ^~~~~~~~~~~~~~
/opt/
I can explain what it expands to
oh ok
no its not that i need an explanation its that its harder to read when its all grouped together like that
ok, how would you format it?
its gonna be hard to reason about at first glance
idk u could format it like normal code and see how it looks ig
without all the other macros, it's basically ```cpp
template<typename Self>
operator decltype([](auto&& self) -> decltype(auto) { return (VA_ARGS); }(std::declval<Self>()))(this Self&& self)
and then the normal noexcept/requires/body
name_of() thing https://godbolt.org/z/q3zGx3Eoa
@late ore https://godbolt.org/z/oTb4fh5sE
yes
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/meta/meta.hpp ```cpp
std::println("{}", xte::meta::name_of(^^const int*(&&)(...) noexcept));
Please don't cross-post the same message across multiple channels (#lobby, #1162965399684534313). Pick the most appropriate channel for your question and ask there.
(const int*(...) noexcept)&&
smh
documented compiler/platform/architecture detection macros
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/meta/meta.hpp ```cpp
#include <print>
template<auto> int x;
int main() {
std::println("{}", xte::meta::name_of(^^x<[] {}>));
}
x<main()::<lambda>{}>
alright
;compile gsnapshot -std=c++26 -freflection -include/opt/compiler-explorer/libs/xieite/main/include/xte/sys/available_memory.hpp ```cpp
std::println("{}", xte::available_memory());
16469725160
now create formatter which will write gigabytes megabytes etc etc
fun
that not that hard
what about mebibytes and gibibytes
xte::big_int for what
wdym
like you still can implement for everything what IEC define 
what is IEC?
ah yes
thanks for xieite


