Skip to content

Instantly share code, notes, and snippets.

@Trass3r
Created November 19, 2019 11:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Trass3r/aa46ddf9b9fc1f2236c5f3926c6e6862 to your computer and use it in GitHub Desktop.
Save Trass3r/aa46ddf9b9fc1f2236c5f3926c6e6862 to your computer and use it in GitHub Desktop.
unique_resource tests
#include <memory>
#include <stdio.h>
#include <type_traits>
template <typename T, typename D>
auto unique_resource(T* t, D&& d)
{
return std::unique_ptr<T, D>(t, std::forward<D>(d));
}
auto test(FILE* file)
{
auto f = unique_resource(file, fclose);
return sizeof(f);
}
auto test2(FILE* file)
{
auto f = unique_resource(file, [](FILE* f){ fclose(f); });
return sizeof(f);
}
auto unique_file(FILE* file)
{
return unique_resource(file, [](FILE* f){ fclose(f); });
}
template <auto cleanup, typename T>
auto unique_resource2(T* t)
{
// return std::unique_ptr<T, decltype(d)>(t, d); //16 bytes!
// return unique_resource(t, [](T* x){ return cleanup(x); });
auto wrap = [](T* t){ cleanup(t); };
return std::unique_ptr<T, decltype(wrap)>(t, wrap);
}
auto test3(FILE* file)
{
auto f = unique_resource2<fclose>(file);
return sizeof(f);
}
auto unique_file2(FILE* file)
{
return unique_resource2<fclose>(file);
}
#if 0
template <typename T, auto d>
auto f() { return [](T* t){ d(t); }; }
template <typename T, auto d>
using unique_resource17 = std::unique_ptr<T, decltype(f<T, d>())>;
using unique_file = unique_resource17<fclose, FILE>;
#endif
template <auto f>
struct FunctionWrapper
{
template <typename... T>
auto operator()(T... args)
{
return f(std::forward<T>(args)...);
}
};
template <typename T, auto cleanup>
using unique_resource17 = std::unique_ptr<T, FunctionWrapper<cleanup>>;
auto test4(FILE* file)
{
using unique_file = unique_resource17<FILE, fclose>;
auto f = unique_file(file);
return sizeof(f);
}
#if 0
template <typename T>
using unique_resource3 = std::unique_ptr<T, void (*)(T*)>;
unique_resource3<FILE>(0, fclose);
template <typename T, void (*)(T*) d>
auto unique_resource22(T* t)
{
return std::unique_ptr<T, decltype(d)>(t, d);
}
auto test44(FILE* file)
{
auto f = unique_resource22<fclose>(file);
return sizeof(f);
}
#endif
#if __cplusplus > 201703L
template <typename T, auto cleanup>
using unique_resource20 = std::unique_ptr<T, decltype([](T* t){ cleanup(t); })>;
auto test20(FILE* file)
{
using unique_file = unique_resource20<FILE, fclose>;
auto f = unique_file(file);
return sizeof(f);
}
#endif
template <auto c, auto d, typename... T>
auto make_unique_resource(T... args)
{
auto* resource = c(std::forward<T>(args)...);
//return std::unique_ptr<decltype(*resource), decltype(d)>(resource, d);
return unique_resource(resource, [](auto x){ d(x); });
}
template <typename... T>
auto make_unique_file(T... args)
{
return make_unique_resource<fopen, fclose>(std::forward<T>(args)...);
}
auto test14()
{
// using unique_file = std::unique_ptr<FILE, decltype([](FILE* f){ return fclose(f); })>;
auto f = make_unique_resource<fopen, fclose>("f.txt", "r");
auto g = make_unique_file("f.txt", "r");
return sizeof(f);
}
template <class T, typename R>
T getParamType( R (*f)(T) );
template <auto f>
using ResourceType = std::remove_pointer_t<decltype(getParamType(f))>;
template <auto c, auto d>
struct make_unique_resource2 : std::unique_ptr<ResourceType<d>, FunctionWrapper<d>>
{
using Base = std::unique_ptr<ResourceType<d>, FunctionWrapper<d>>;
template <typename... T>
make_unique_resource2(T... args)
: Base(c(std::forward<T>(args)...))
{
}
};
using make_unique_file2 = make_unique_resource2<fopen, fclose>;
auto test15()
{
// using unique_file = std::unique_ptr<FILE, decltype([](FILE* f){ return fclose(f); })>;
// auto f = make_unique_resource<fopen, fclose>("f.txt", "r");
auto f = make_unique_file2("f.txt", "r");
return sizeof(f);
}
template <typename R, intptr_t invalid, auto c, auto d>
struct unique_resource23 : std::unique_ptr<std::remove_pointer_t<R>, FunctionWrapper<d>>
{
using Base = std::unique_ptr<std::remove_pointer_t<R>, FunctionWrapper<d>>;
using Base::Base;
#if 1
template <typename... T>
unique_resource23(T... args)
: Base(c(std::forward<T>(args)...))
{
}
#endif
~unique_resource23()
{
if (this->get() == R(invalid))
this->release();
}
explicit operator bool() const
{
return this->get() != invalid;
}
};
auto test17()
{
using unique_file = unique_resource23<FILE*, nullptr, fopen, fclose>;
auto f = unique_file("f.txt", "r");
if (!f) return;
f.get();
//auto f = unique_file(fopen("f.txt", "r"));
}
typedef void* HANDLE;
//HANDLE INVALID_HANDLE_VALUE = -1;
//#define INVALID_HANDLE_VALUE ((HANDLE)(size_t)-1)
const auto INVALID_HANDLE_VALUE = HANDLE(-1);
HANDLE CreateFile(
const char* lpFileName,
);
int CloseHandle(
HANDLE hObject
);
auto test18()
{
using unique_file = unique_resource23<HANDLE, -1, CreateFile, CloseHandle>;
auto f = unique_file("f.txt");
//auto f = unique_file(fopen("f.txt", "r"));
return sizeof(f);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment