Created
November 19, 2019 11:19
-
-
Save Trass3r/aa46ddf9b9fc1f2236c5f3926c6e6862 to your computer and use it in GitHub Desktop.
unique_resource tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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