diff options
author | David Robillard <d@drobilla.net> | 2018-06-16 10:26:47 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2023-12-02 18:49:08 -0500 |
commit | 8fb8b922fb7575d7aed2f2184a02586b56ba873a (patch) | |
tree | 06ea3a48cefb5cb221359b17911380460e68e7c8 /bindings/cpp/include/serd/detail/Wrapper.hpp | |
parent | 74ddf7934336f16dcdce688333040d82972817fc (diff) | |
download | serd-8fb8b922fb7575d7aed2f2184a02586b56ba873a.tar.gz serd-8fb8b922fb7575d7aed2f2184a02586b56ba873a.tar.bz2 serd-8fb8b922fb7575d7aed2f2184a02586b56ba873a.zip |
[WIP] Add C++ bindings
Diffstat (limited to 'bindings/cpp/include/serd/detail/Wrapper.hpp')
-rw-r--r-- | bindings/cpp/include/serd/detail/Wrapper.hpp | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/bindings/cpp/include/serd/detail/Wrapper.hpp b/bindings/cpp/include/serd/detail/Wrapper.hpp new file mode 100644 index 00000000..887e6643 --- /dev/null +++ b/bindings/cpp/include/serd/detail/Wrapper.hpp @@ -0,0 +1,138 @@ +// Copyright 2019-2021 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +#ifndef SERD_DETAIL_WRAPPER_HPP +#define SERD_DETAIL_WRAPPER_HPP + +// IWYU pragma: no_include "serd/serd.h" + +#include <cstddef> +#include <memory> +#include <type_traits> +#include <utility> + +namespace serd { + +/// Utility template for a mutable type which removes const if necessary +template<class T> +class Optional; + +/// Detail namespace +namespace detail { + +/** + @defgroup serdpp_detail API Details + Internal C++ wrapper details that should not be used directly by clients. + @ingroup serdpp + @{ +*/ + +/// Utility template for a mutable type which removes const if necessary +template<class T> +using Mutable = typename std::remove_const_t<T>; + +/// Generic C++ wrapper for a C object +template<class T, class Deleter> +class Wrapper +{ +public: + using CType = T; + + explicit Wrapper(T* ptr) + : _ptr{ptr, Deleter{}} + {} + + Wrapper(T* ptr, Deleter deleter) + : _ptr{ptr, std::move(deleter)} + {} + + explicit Wrapper(std::unique_ptr<T, Deleter> ptr) + : _ptr{std::move(ptr)} + {} + + Wrapper(Wrapper&&) noexcept = default; + Wrapper& operator=(Wrapper&&) noexcept = default; + + Wrapper(const Wrapper&) = delete; + Wrapper& operator=(const Wrapper&) = delete; + + ~Wrapper() = default; + + /// Return a pointer to the underlying C object + T* cobj() { return _ptr.get(); } + + /// Return a pointer to the underlying C object + const T* cobj() const { return _ptr.get(); } + +protected: + friend class Optional<T>; + + explicit Wrapper(std::nullptr_t) + : _ptr{nullptr} + {} + + void reset() { _ptr.reset(); } + + std::unique_ptr<T, Deleter> _ptr; +}; + +/// Free function for an object that can free itself +template<class T> +using StandaloneFreeFunc = void(Mutable<T>*); + +/// Free function for an object managed via an allocator +template<class T> +using AllocatedFreeFunc = void(ZixAllocator*, Mutable<T>*); + +/** + Simple overhead-free deleter for a C object. + + Can be used with const or mutable pointers, but only mutable pointers will + be freed. In other words, mutability implies ownership, and this can not + handle unowned mutable pointers. + + @ingroup serdpp_detail +*/ +template<class T, StandaloneFreeFunc<T> free> +struct StandaloneDeleter { + template<class = std::enable_if<!std::is_const<T>::value>> + void operator()(Mutable<T>* const ptr) + { + free(ptr); + } + + template<class = std::enable_if<std::is_const<T>::value>> + void operator()(const T*) + {} +}; + +/** + Simple overhead-free deleter for a C object. + + Can be used with const or mutable pointers, but only mutable pointers will + be freed. In other words, mutability implies ownership, and this can not + handle unowned mutable pointers. + + @ingroup serdpp_detail +*/ +template<class T, AllocatedFreeFunc<T> free> +struct AllocatedDeleter { + template<class = std::enable_if<!std::is_const<T>::value>> + void operator()(Mutable<T>* const ptr) + { + free(nullptr, ptr); + } + + template<class = std::enable_if<std::is_const<T>::value>> + void operator()(const T*) + {} +}; + +/** + @} +*/ + +} // namespace detail +} // namespace serd + +#endif // SERD_DETAIL_WRAPPER_HPP |