Skip to content

Commit

Permalink
ptr-wrapper: Initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
RandomSpaceship committed Dec 26, 2024
1 parent 19a4c7e commit 4d645c7
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 0 deletions.
1 change: 1 addition & 0 deletions software/shared/overlay.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ final: prev: {
hi-can = final.callPackage ./hi-can { };
hi-can-raw = final.callPackage ./hi-can-raw { };
hi-can-net = final.callPackage ./hi-can-net { };
ptr-wrapper = final.callPackage ./ptr-wrapper { };
}
83 changes: 83 additions & 0 deletions software/shared/ptr-wrapper/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# PROJECT SETUP
cmake_minimum_required(VERSION 3.23)

project(
ptr_wrapper
VERSION 0.0.1
LANGUAGES CXX)

# credit https://www.kitware.com/cmake-and-the-default-build-type/
set(default_build_type "Debug")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(
STATUS
"Setting build type to '${default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE
"${default_build_type}"
CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
endif()
# we always want debug info for stack tracing, so switch to RelWithDebInfo from
# Release
if(CMAKE_BUILD_TYPE STREQUAL "Release")
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
endif()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# Add -Werror flag for release builds
if(CMAKE_BUILD_TYPE MATCHES "Rel.*")
add_compile_options(-Werror)
endif()

# Set the C++ standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# COMPILE (Libraries)

# Find all source files in the src directory
file(GLOB_RECURSE CODE_SOURCES src/*.cpp)
# Add the target with those sources
add_library(${PROJECT_NAME} SHARED ${CODE_SOURCES})
# Set the include directories for the library
target_include_directories(
${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include/${PROJECT_NAME}>)

# INSTALL (Libraries)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

# CMake packaging - see https://blog.vito.nyc/posts/cmake-pkg/ for a good
# explanation
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake @ONLY)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
COMPATIBILITY SameMinorVersion)

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME})

# Headers
install(DIRECTORY include/ DESTINATION include/${PROJECT_NAME})

# Versioning
set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION})
# The main install - default locations are fine
install(
TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}_targets
ARCHIVE
LIBRARY
RUNTIME)

# The last of the CMake packaging info
install(EXPORT ${PROJECT_NAME}_targets
DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME})
1 change: 1 addition & 0 deletions software/shared/ptr-wrapper/config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@_targets.cmake)
17 changes: 17 additions & 0 deletions software/shared/ptr-wrapper/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
stdenv,
cleanCmakeSource,
cmake,
}:

stdenv.mkDerivation rec {
pname = "ptr-wrapper";
version = "0.0.1";

src = cleanCmakeSource {
src = ./.;
name = pname;
};

nativeBuildInputs = [ cmake ];
}
83 changes: 83 additions & 0 deletions software/shared/ptr-wrapper/include/ptr_wrapper.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#pragma once

#include <functional>
#include <stdexcept>

/// @brief A wrapper around a pointer which will automatically deallocate the resource when it goes out of scope
/// @details Intended for use in situations where @ref shared_ptr can't be used, such as when the resource is not allocated with `new`
template <typename T>
class PtrWrapper
{
public:
PtrWrapper() = default;
PtrWrapper(T* ptr, std::function<void(T*)> deallocator)
: PtrWrapper([ptr](void)
{ return ptr; }, deallocator) {}
PtrWrapper(std::function<T*(void)> allocator, std::function<void(T*)> deallocator)
: _deallocator(deallocator)
{
if (!allocator)
throw std::invalid_argument("Allocator must be provided");
if (!deallocator)
throw std::invalid_argument("Deallocator must be provided");
_ptr = allocator();
}

~PtrWrapper()
{
try
{
if (_ptr)
_deallocator(_ptr);
}
catch (...)
{
// ignore - since we're in a destructor, we can't throw
}
}

// we do NOT want to allow copying, that doesn't make sense.
// Moving is OK though
PtrWrapper(const PtrWrapper&) = delete;
PtrWrapper(PtrWrapper&& other) noexcept
{
swap(*this, other);
}
PtrWrapper& operator=(PtrWrapper) = delete;
PtrWrapper& operator=(PtrWrapper&& other) noexcept
{
swap(*this, other);
return *this;
}

PtrWrapper& operator=(T* ptr)
{
if (_ptr)
_deallocator(_ptr);
_ptr = ptr;
return *this;
}

T** operator&()
{
return &_ptr;
}

friend void swap(PtrWrapper& first, PtrWrapper& second)
{
using std::swap;
swap(first._ptr, second._ptr);
swap(first._deallocator, second._deallocator);
}

// allow all the common methods of getting the file descriptor/"dereferencing"
virtual inline explicit operator T*() const { return get(); }
virtual inline T* operator*() const { return get(); }
virtual inline T* operator->() const { return get(); }
virtual inline T* get() const { return _ptr; }

private:
T* _ptr = nullptr;

std::function<void(T*)> _deallocator = nullptr;
};
1 change: 1 addition & 0 deletions software/shared/ptr-wrapper/src/ptr_wrapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "ptr_wrapper.hpp"

0 comments on commit 4d645c7

Please sign in to comment.