Постироничные идеи для ебаного C++ – Telegram
Постироничные идеи для ебаного C++
323 subscribers
51 photos
1 video
2 files
20 links
Download Telegram
Ребятки, а подскажите, что тут надо поправить, чтобы деструктор B вызвался?
😁8🤔3
std::unique_ptr является практически универсальным афинным хэндлом.

Его можно использовать как move-only RAII обёртку для практически любого хэндла, не переплачивая по памяти. (А в человеческих ABI - и по скорости тоже.) Главное, чтобы у хэндла было какое-нибудь null-значение.

Особенно полезно при оборачивании сишных 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
👍8😁4❤‍🔥2
Прогнать Ве Крест Крест через @ZoVifyBot
🥴6👏1
прислать в gcc патч, делающий -ferror-limit алиасом на -fmax-errors
прислать в clang патч, делающий -fmax-errors алиасом на -ferror-limit
🤔4👏3🥴2
vkCmdBegin(cb, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
vkCmdColor3f(cb, 1.f, 0.f, 0.f);
vkCmdVertex2f(cb, -0.5f, -0.5f);
vkCmdColor3f(cb, 0.f, 1.f, 0.f);
vkCmdVertex2f(cb, 0.f, 0.5f);
vkCmdColor3f(cb, 0.f, 0.f, 1.f);
vkCmdVertex2f(cb, 0.5f, -0.5f);
vkCmdEnd(cb);
        if (it != nullptr && *it != nullptr && **it != nullptr && ***it != nullptr) {
(**it)(this);
}
🤣11
Forwarded from Хꙫмяк
❤‍🔥7

template <class T, class E>
struct Result : public Either<T, E> {

template <class V>
Result(V&& v) : Either<T, E>(std::forward<V>(v)) {
}
template <class V>
Result(const V& v) : Either<T, E>(v) {
}

auto Ok() const noexcept -> bool {
return this->template Is<T>();
}

auto Unwrap() -> T& {
try {
return this->template As<T>();
} catch (...) {
throw this->template As<E>();
}
}

auto Err() -> E {
return this->template As<E>();
}

auto operator!() -> T& {
return Unwrap();
}
};


auto Res() -> monad::Result<monad::Unit, err::RuntimeError> {
return err::RuntimeError("LOL");
}

auto Throws() -> void {
!Res();
}
🔥4
#include <string>
#include <fmt/format.h>

template<typename F>
struct Scope_exit {
F f;
Scope_exit(F f): f(std::move(f)) {}
~Scope_exit() { f(); }
};

auto make_string() {
std::string result;

Scope_exit guard = [&] {
fmt::println("About to return '{}'", result);
};

for (int i = 0; i < 20; i++) {
result += std::to_string(i);
}

return result;
}

int main() {
auto s = make_string();
}


$ # Either behavior is legal of a C++ compiler
$ g++ a.cpp -lfmt -o a && ./a
About to return '012345678910111213141516171819'
$ g++ a.cpp -lfmt -o a -fno-elide-constructors && ./a
About to return ''
🥴3👍2
Forwarded from Random Rust Dev
Когда надоело говорить "боровить", говори "реквизировать"
😁7
auto(*foo)(size_t)->void* {
malloc //
};
🥰6
6👏1😁1
&*iovecs_.begin()
👍1
Постироничные идеи для ебаного C++
&*iovecs_.begin()
using T = std::iter_value_t<decltype(iovecs_.begin())>;
if constexpr(std::is_same_v<std::vector<T>, decltype(iovecs_)>) {
auto* ptr =reinterpret_cast<T*>(iovecs_.begin());
}