diff options
-rw-r--r-- | gfx/window.cpp | 7 | ||||
-rw-r--r-- | gfx/window.h | 7 | ||||
-rw-r--r-- | lib/ptr.hpp | 65 | ||||
-rw-r--r-- | test/Jamfile.jam | 4 | ||||
-rw-r--r-- | test/test-collection.cpp | 38 |
5 files changed, 105 insertions, 16 deletions
diff --git a/gfx/window.cpp b/gfx/window.cpp index 2e3c843..dd300a7 100644 --- a/gfx/window.cpp +++ b/gfx/window.cpp @@ -3,10 +3,9 @@ #include <stdexcept>
Window::Window(int width, int height, const std::string & title) :
- m_window {m_window.create(SDL_CreateWindow, SDL_DestroyWindow, title.c_str(),
- static_cast<int>(SDL_WINDOWPOS_CENTERED), static_cast<int>(SDL_WINDOWPOS_CENTERED), width, height,
- static_cast<Uint32>(SDL_WINDOW_OPENGL))},
- m_glContext {m_glContext.create(SDL_GL_CreateContext, SDL_GL_DeleteContext, m_window)}
+ m_window {title.c_str(), static_cast<int>(SDL_WINDOWPOS_CENTERED), static_cast<int>(SDL_WINDOWPOS_CENTERED), width,
+ height, static_cast<Uint32>(SDL_WINDOW_OPENGL)},
+ m_glContext {m_window}
{
if (glewInit() != GLEW_OK) {
throw std::runtime_error {"Glew failed to initialize!"};
diff --git a/gfx/window.h b/gfx/window.h index 3ac583f..252ccaa 100644 --- a/gfx/window.h +++ b/gfx/window.h @@ -19,8 +19,11 @@ public: void SwapBuffers() const;
private:
- wrapped_ptr<SDL_Window> m_window;
- wrapped_ptr<std::remove_pointer_t<SDL_GLContext>> m_glContext;
+ using GL_Context = std::remove_pointer_t<SDL_GLContext>;
+ using SDL_WindowPtr = wrapped_ptrt<SDL_Window, SDL_CreateWindow, SDL_DestroyWindow>;
+ using SDL_GLContextPtr = wrapped_ptrt<GL_Context, SDL_GL_CreateContext, SDL_GL_DeleteContext>;
+ SDL_WindowPtr m_window;
+ SDL_GLContextPtr m_glContext;
};
#endif
diff --git a/lib/ptr.hpp b/lib/ptr.hpp index 0b00285..f242670 100644 --- a/lib/ptr.hpp +++ b/lib/ptr.hpp @@ -2,23 +2,68 @@ #define PTR_H #include <memory> +#include <special_members.hpp> -template<typename Obj> class wrapped_ptr : public std::unique_ptr<Obj, void (*)(Obj *)> { +template<typename Obj, auto Destroy> class wrapped_ptr { public: - using std::unique_ptr<Obj, void (*)(Obj *)>::unique_ptr; - wrapped_ptr() : std::unique_ptr<Obj, void (*)(Obj *)> {{}, {}} { } + template<typename... Args, typename... Params> + explicit wrapped_ptr(Obj * (*factory)(Params...), Args &&... args) : obj {factory(std::forward<Args>(args)...)} + { + } - inline - operator Obj *() const + explicit wrapped_ptr(wrapped_ptr && p) : obj {p.obj} { - return this->get(); + p.obj = nullptr; } - template<typename... Args, typename... Params> - static auto - create(Obj * (*factory)(Params...), void (*deleter)(Obj *), Args &&... args) + ~wrapped_ptr() + { + if (obj) { + Destroy(obj); + } + } + + NO_COPY(wrapped_ptr); + + wrapped_ptr & + operator=(wrapped_ptr && p) + { + if (obj) { + Destroy(obj); + } + obj = p.obj; + p.obj = nullptr; + return *this; + } + + [[nodiscard]] inline + operator Obj *() const noexcept + { + return obj; + } + + [[nodiscard]] inline auto + operator->() const noexcept + { + return obj; + } + + [[nodiscard]] inline auto + get() const noexcept + { + return obj; + } + +protected: + explicit wrapped_ptr(Obj * o) : obj {o} { } + Obj * obj; +}; + +template<typename Obj, auto Create, auto Destroy> class wrapped_ptrt : public wrapped_ptr<Obj, Destroy> { +public: + template<typename... Args> + explicit wrapped_ptrt(Args &&... args) : wrapped_ptr<Obj, Destroy> {Create(std::forward<Args>(args)...)} { - return wrapped_ptr<Obj> {factory(std::forward<Args>(args)...), deleter}; } }; diff --git a/test/Jamfile.jam b/test/Jamfile.jam index 8a9843c..82ca894 100644 --- a/test/Jamfile.jam +++ b/test/Jamfile.jam @@ -13,6 +13,10 @@ project : requirements <library>boost_unit_test_framework <library>..//ilt <toolset>tidy:<xcheckxx>hicpp-vararg + <toolset>tidy:<suppress>accessMoved + <toolset>tidy:<xcheckxx>bugprone-use-after-move + <toolset>tidy:<xcheckxx>hicpp-invalid-access-moved + <toolset>tidy:<xcheckxx>clang-analyzer-cplusplus.Move ; run test-collection.cpp ; diff --git a/test/test-collection.cpp b/test/test-collection.cpp index 1286733..6e54da3 100644 --- a/test/test-collection.cpp +++ b/test/test-collection.cpp @@ -4,6 +4,7 @@ #include <collection.hpp> #include <memory> +#include <ptr.hpp> #include <special_members.hpp> #include <vector> @@ -64,3 +65,40 @@ BOOST_AUTO_TEST_CASE(a_sub) } BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_CASE(wrapped_ptr_file_cons) +{ + using FilePtr = wrapped_ptr<FILE, &fclose>; + FilePtr fp {fopen, "/dev/null", "r"}; + BOOST_REQUIRE(fp); + BOOST_CHECK_NO_THROW(fflush(fp)); + + BOOST_CHECK_EQUAL(fp.get(), fp.operator->()); + BOOST_CHECK_EQUAL(fp.get(), fp.operator FILE *()); +} + +BOOST_AUTO_TEST_CASE(wrapped_ptr_file_move) +{ + using FilePtr = wrapped_ptr<FILE, &fclose>; + FilePtr fp {fopen, "/dev/null", "r"}; + BOOST_REQUIRE(fp); + + FilePtr fp2 {std::move(fp)}; + BOOST_REQUIRE(!fp); + BOOST_REQUIRE(fp2); + + fp = std::move(fp2); + BOOST_REQUIRE(fp); + BOOST_REQUIRE(!fp2); + + FilePtr fp3 {fopen, "/dev/null", "r"}; + fp = std::move(fp3); +} + +BOOST_AUTO_TEST_CASE(wrapped_ptr_file_typed) +{ + using FilePtr = wrapped_ptrt<FILE, &fopen, &fclose>; + FilePtr fp {"/dev/null", "r"}; + BOOST_REQUIRE(fp); + BOOST_CHECK_NO_THROW(fflush(fp)); +} |