#![no_main]
#[link_section=".text"]
#[no_mangle]
pub static main: [u32; 9] = [
3237986353,
3355442993,
120950088,
822083584,
252621522,
1699267333,
745499756,
1919899424,
169960556,
];
👍6
В std::function нельзя сложить лямбду которая захватила uptr
https://godbolt.org/z/jr3oxj1hd дрался с компилятором. Победил и проиграл одновременно(он компилит без ошибки, но не линкуется)
godbolt.org
Compiler Explorer - C++
namespace {
struct A{
int i;
};
}
template<typename... Ts>
auto tupleAlloc(std::tuple<Ts...>&& args) {
auto lamb = [&](Ts... args) {
return std::make_unique<std::tuple<std::decay_t<Ts>...>>(args...);
};
return std::apply(std::move(lamb)…
struct A{
int i;
};
}
template<typename... Ts>
auto tupleAlloc(std::tuple<Ts...>&& args) {
auto lamb = [&](Ts... args) {
return std::make_unique<std::tuple<std::decay_t<Ts>...>>(args...);
};
return std::apply(std::move(lamb)…
struct slice {
T* ptr; // петербург
size_t len; // ленобласть
};😁12🤡1🤣1
Forwarded from Андрей Будиловский
Если вы понимаете этот код, то вам открыт доступ в айти-канал с мемами для программистов 👇
template <typename T, typename... Args,
typename = std::void_t<decltype(::new(std::declval<void*>()) T(std::declval<Args>()...))>>
AA_ALWAYS_INLINE constexpr T* construct_at(const T* location, Args&&... args) noexcept(noexcept(
::new(const_cast<void*>(static_cast<const volatile void*>(location))) T(std::forward<Args>(args)...))) {
return ::new (const_cast<void*>(static_cast<const volatile void*>(location)))
T(std::forward<Args>(args)...);
}
template <typename T, typename... Args,
typename = std::void_t<decltype(::new(std::declval<void*>()) T(std::declval<Args>()...))>>
AA_ALWAYS_INLINE constexpr T* construct_at(const T* location, Args&&... args) noexcept(noexcept(
::new(const_cast<void*>(static_cast<const volatile void*>(location))) T(std::forward<Args>(args)...))) {
return ::new (const_cast<void*>(static_cast<const volatile void*>(location)))
T(std::forward<Args>(args)...);
}
😁1
Forwarded from Vladimir🏴☠️ [🥴] 💅
#include <cinttypes>
#include <string>
#include <variant>
#include <optional>
#include <vector>
using u8 =uint8_t;
using i8 = int8_t;
using u16= uint16_t;
using i16 = int16_t;
using u32= uint32_t;
using i32 = int32_t;
using u64 = uint64_t;
using i64 = int64_t;
using usize = size_t;
using isize = ptrdiff_t;
using f32 = float;
using f64 = double;
using String = std::string;
template <typename T>
using Vec = std::vector<T>;
template <typename T>
using Option = std::optional<T>;
Программируйте на плюсах правильно!
#include <string>
#include <variant>
#include <optional>
#include <vector>
using u8 =uint8_t;
using i8 = int8_t;
using u16= uint16_t;
using i16 = int16_t;
using u32= uint32_t;
using i32 = int32_t;
using u64 = uint64_t;
using i64 = int64_t;
using usize = size_t;
using isize = ptrdiff_t;
using f32 = float;
using f64 = double;
using String = std::string;
template <typename T>
using Vec = std::vector<T>;
template <typename T>
using Option = std::optional<T>;
Программируйте на плюсах правильно!
❤1
trait Abs { fn abs(self) -> Self; }
impl Abs for i64 {
fn abs(self) -> Self { 2 * self }
}
fn main() {
let x = 42;
println!("{} {}", x.abs(), x.abs());
}$ rustc abs.rs -o abs && ./abs
84 42
🤯3🤨1
error-log
9 MB
namespace ns {
struct Foo;
using Foo = int;
}
#include <fmt/format.h>$ time g++-13 -std=gnu++20 -c foo.cpp 2>error-log
real 1m44.740s
user 1m44.370s
sys 0m0.313s
$ du -h error-log
9.1M error-log
🤯2😁1
План по развалу проклятой Америки:
1. Присоединяем Грузию к США как штат
2. Нарушается ODR, пендосы переиграны
1. Присоединяем Грузию к США как штат
2. Нарушается ODR, пендосы переиграны
👍7
std::ranges она как девушка, конфетно-букетный период проходит и без макияжа уже не кажется так красиво
#define SIDE_EFFECT_VIEW(closure) \
std::views::transform([&](auto&& i) { \
closure(); \
return std::move(i); \
})
auto BitInverseShuffle(std::vector<int>& data) -> void {
const int size = data.size();
int j = 0;
std::ranges::for_each(std::views::iota(0, size) | SIDE_EFFECT_VIEW([&]() {
int bit = size >> 1;
for (; j & bit; bit >>= 1) {
j ^= bit;
}
j ^= bit;
}) | std::views::filter([&j](int i) { return i < j; }),
[&j, &data](int i) { std::swap(data[i], data[j]); });
}
😁4
Мало кто знает, но JavaScript унаследовал от C-семейства не только фигурные скобки, но и свои знаменитые опциональные точки с запятой.
Например, в C++ можно смело опускать точку с запятой после
Например, в C++ можно смело опускать точку с запятой после
return в следующем коде:void add_if_missing(std::vector<Item>& v, Item item) {
if (std::ranges::find(v, item) != v.end())
return;
v.push_back(item);
}👍8
Forwarded from Ваня Не проблема
Ребятки, а подскажите, что тут надо поправить, чтобы деструктор B вызвался?
😁8🤔3
std::unique_ptr является практически универсальным афинным хэндлом.
Его можно использовать как move-only RAII обёртку для практически любого хэндла, не переплачивая по памяти.(А в человеческих ABI - и по скорости тоже.) Главное, чтобы у хэндла было какое-нибудь null-значение.
Особенно полезно при оборачивании сишных API.
Допустим, у нас есть OpenGL текстуры. Вообще OpenGL использует
Эта обёртка невладеющая. Она удовлетворяет концепту NullablePointer, типы которого умеет оборачивать
Заметим, что мы не переплатили:
Теперь напишем кастомный deleter для
Как известно, если существует тип
Напишем наконец владеющую обёртку:
Уже можно пользоваться! осталось только заметить, что мы написали замену
Выделение из этого примера бойлерплейта в утилитарные шаблоны предоставляется читателю как упражнение.
Его можно использовать как move-only RAII обёртку для практически любого хэндла, не переплачивая по памяти.
Особенно полезно при оборачивании сишных API.
Допустим, у нас есть OpenGL текстуры. Вообще OpenGL использует
GLuint для почти всех хэндлов, так что сделаем типобезопасную обёртку:struct GL_texture_handle {
GLuint id = 0;
GL_texture_handle() = default;
GL_texture_handle(std::nullptr_t) {}
explicit operator bool() const { return id != 0; }
bool operator==(const GL_texture_handle&) const = default;
};Эта обёртка невладеющая. Она удовлетворяет концепту NullablePointer, типы которого умеет оборачивать
unique_ptr. Заметим, что этому концепту не нужно разыменование (для непрозрачных хэндлов оно бессмысленно), а нужно только null-значение и интерфейс к нему через сравнимость с nullptr. Причём это null-значение может быть таким, каким требует предметная область: 0, -1, что-нибудь нечётное, особое значение структуры и т.п. Главное, чтобы мы думали про него, когда нам говорят про nullptr.Заметим, что мы не переплатили:
// 4 на любой платформе согласно спеке OpenGL
static_assert(sizeof(GL_texture_handle) == sizeof(GLuint));
Теперь напишем кастомный deleter для
unique_ptr.struct GL_texture_deleter {
using pointer = GL_texture_handle;
void operator()(pointer handle) const {
glDeleteTextures(1, &handle.id);
}
};Как известно, если существует тип
Deleter::pointer, то std::unique_ptr<T, Deleter> будет хранить внутри себя не T*, а Deleter::pointer. Мы вообще проигнорируем T.Напишем наконец владеющую обёртку:
using Unique_GL_texture = std::unique_ptr<void, GL_texture_deleter>;
static_assert(sizeof(Unique_GL_texture) == sizeof(GLuint)); // !!!
Уже можно пользоваться! осталось только заметить, что мы написали замену
std::default_delete, но не написали замены std::make_unique.Unique_GL_texture make_gl_texture(GLenum target) {
GL_texture_handle handle;
glCreateTextures(target, 1, &handle.id);
return Unique_GL_texture(handle);
}Выделение из этого примера бойлерплейта в утилитарные шаблоны предоставляется читателю как упражнение.
👍8