Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
SC::UniqueHandle< Definition > Struct Template Reference

Move only handle that has a special tag value flagging its invalid state. More...

#include <UniqueHandle.h>

Public Types

using Handle = typename Definition::Handle
 

Public Member Functions

 UniqueHandle (const UniqueHandle &v)=delete
 
UniqueHandleoperator= (const UniqueHandle &other)=delete
 
 UniqueHandle (UniqueHandle &&v)
 
 UniqueHandle (const Handle &externalHandle)
 
Result assign (UniqueHandle &&other)
 Move assigns another UniqueHandle to this object, eventually closing existing handle.
 
Result assign (const Handle &externalHandle)
 Copy assigns another UniqueHandle to this object, eventually closing existing handle.
 
UniqueHandleoperator= (UniqueHandle &&other)
 
bool isValid () const
 Check if current handle is valid.
 
void detach ()
 Detaches (sets to invalid) current handle, without closing it.
 
Result get (Handle &outHandle, Result invalidReturnType) const
 Extracts the native operating system handle out.
 
Result close ()
 Closes the handle by calling its OS specific close function.
 

Static Public Attributes

static constexpr Handle Invalid = Definition::Invalid
 

Protected Attributes

Handle handle = Invalid
 

Detailed Description

template<typename Definition>
struct SC::UniqueHandle< Definition >

Move only handle that has a special tag value flagging its invalid state.


Typically used to wrap Operating System specific handles.

Template Parameters
DefinitionA struct declaring handle type, release function and invalid handle value.

Example:

... definition in header

struct SC_COMPILER_EXPORT FileDescriptorDefinition
{
using Handle = int; // fd
static Result releaseHandle(Handle& handle);
static constexpr Handle Invalid = -1; // invalid fd
};

... derive from it

struct SC_COMPILER_EXPORT FileDescriptor : public UniqueHandle<detail::FileDescriptorDefinition>
{
using UniqueHandle::UniqueHandle;

...declaration in .cpp file

#include <errno.h> // errno
#include <fcntl.h> // fcntl
#include <sys/stat.h> // fstat
#include <unistd.h> // close
//-------------------------------------------------------------------------------------------------------
// FileDescriptorDefinition
//-------------------------------------------------------------------------------------------------------
SC::Result SC::detail::FileDescriptorDefinition::releaseHandle(Handle& handle)
{
if (::close(handle) != 0)
{
return Result::Error("FileDescriptorDefinition::releaseHandle - close failed");
}
return Result(true);
}

...usage

#include <fcntl.h> // for open
SC::Result SC::FileTest::snippetForUniqueHandle()
{
StringPath filePath;
SC_TRY(filePath.path.assign("someFile.txt"));
const int flags = O_RDWR | O_CREAT | O_TRUNC; // Open for read/write, create if not exists, truncate if exists
const int access = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // Read/write for owner, read for group and others
FileDescriptor myDescriptor;
const int nativeFd = ::open(filePath.path.buffer, flags, access);
// Assign the native handle to UniqueHandle (will release the existing one, if any)
SC_TRY(myDescriptor.assign(nativeFd));
// UniqueHandle can only be moved, but not copied
FileDescriptor otherDescriptor = move(myDescriptor);
// FileDescriptor otherDescriptor = myDescriptor; // <- Doesn't compile
// Explicitly close (or it will be automatically released on scope close / destructor)
SC_TRY(otherDescriptor.close());
// If detach() is called, the handle will be made invalid without releasing it
otherDescriptor.detach();
// Check handle for validity
if (otherDescriptor.isValid())
{
// ... do something
}
return Result(true);
}

Member Function Documentation

◆ assign() [1/2]

template<typename Definition >
Result SC::UniqueHandle< Definition >::assign ( const Handle & externalHandle)
inlinenodiscard

Copy assigns another UniqueHandle to this object, eventually closing existing handle.

Parameters
externalHandleThe handle to be copy assigned
Returns
Returns invalid result if close failed

◆ assign() [2/2]

template<typename Definition >
Result SC::UniqueHandle< Definition >::assign ( UniqueHandle< Definition > && other)
inlinenodiscard

Move assigns another UniqueHandle to this object, eventually closing existing handle.

Parameters
otherThe handle to be move-assigned
Returns
Returns invalid result if close failed

◆ close()

template<typename Definition >
Result SC::UniqueHandle< Definition >::close ( )
inlinenodiscard

Closes the handle by calling its OS specific close function.

Returns
true if the handle was closed correctly

◆ detach()

template<typename Definition >
void SC::UniqueHandle< Definition >::detach ( )
inline

Detaches (sets to invalid) current handle, without closing it.

◆ get()

template<typename Definition >
Result SC::UniqueHandle< Definition >::get ( Handle & outHandle,
Result invalidReturnType ) const
inlinenodiscard

Extracts the native operating system handle out.

Parameters
outHandleOutput native OS handle
invalidReturnTypethe value to be returned if this function fails
Returns
invalidReturnType if isValid() == false

◆ isValid()

template<typename Definition >
bool SC::UniqueHandle< Definition >::isValid ( ) const
inlinenodiscard

Check if current handle is valid.

Returns
true if handle is valid

The documentation for this struct was generated from the following file: