xentara-plugin v2.0.4
The Xentara Plugin Framework
Loading...
Searching...
No Matches
xentara::data::WriteHandle Class Referencefinal

A handle for writing a data value. More...

#include <xentara/data/WriteHandle.hpp>

Public Types

enum class  Error {
  NoError , NullHandle , Unknown , ReadOnly ,
  TypeMismatch , OutOfRange , IllegalValue , Defunct ,
  UnknownError
}
 An enum describing read errors. More...
 

Public Member Functions

 WriteHandle ()
 Default constructor.
 
 WriteHandle (Error error)
 Constructor for an error handle that always returns a write error.
 
 WriteHandle (std::error_code error)
 Constructor for an error handle that returns an arbitrary std::error_code.
 
template<memory::ObjectBlockType MemoryBlock>
 WriteHandle (const std::shared_ptr< MemoryBlock > &memoryBlock)
 Constructor for a handle that writes to a memory block.
 
template<memory::ObjectBlockType MemoryBlock>
 WriteHandle (const std::weak_ptr< MemoryBlock > &memoryBlock)
 Constructor for a handle that writes to a memory block.
 
template<typename Type , typename Callback >
requires std::is_invocable_v<const Callback &, Type &&>
 WriteHandle (std::in_place_type_t< Type >, Callback &&callback)
 Constructor for a handle that writes using a callback.
 
template<typename Type , typename Object , typename Callback >
requires std::is_invocable_v<const Callback &, Object &, Type &&>
 WriteHandle (std::in_place_type_t< Type >, Callback &&callback, const std::shared_ptr< Object > &object)
 Constructor for a handle that writes by calling a callback with an object.
 
template<typename Type , typename Object , typename Callback >
requires std::is_invocable_v<const Callback &, Object &, Type &&>
 WriteHandle (std::in_place_type_t< Type >, Callback &&callback, const std::weak_ptr< Object > &object)
 Constructor for a handle that writes by calling a callback with an object.
 
auto nativeType () const noexcept -> NativeType
 Gets the native type of the handle.
 
auto bitSize () const noexcept -> int
 Gets the number of bits that a numeric handle supports.
 
auto typeId () const noexcept -> const std::type_info &
 Gets the precise type ID of the internal type used by the handle.
 
template<typename Type >
auto write (Type &&value) const -> std::error_code
 Writes a value.
 
auto copy (const ReadHandle &readHandle) const -> std::error_code
 Copies a value from a read handle to a write handle.
 
auto hardError () const -> std::error_code
 Gets the error of an error handle.
 
auto operator== (Error error) const -> bool
 Checks whether the handle is an error handle that returns a certain error.
 
auto operator== (const std::error_code &error) const -> bool
 Checks whether the handle is an error handle that returns a certain error.
 

Static Public Member Functions

static auto errorCategory () -> const std::error_category &
 Gets the error category for error codes of type [Error].
 

Detailed Description

A handle for writing a data value.

Member Enumeration Documentation

◆ Error

An enum describing read errors.

Enumerator
NoError 

No error occurred.

NullHandle 

The handle is not associated with any target value.

Unknown 

The target value's identity could not be resolved. This value is returned for unknown or unsupported attributes, for example.

ReadOnly 

The target value is read-only.

TypeMismatch 

The supplied value could not be converted to the required type.

OutOfRange 

The supplied value is out of range.

IllegalValue 

The supplied value is not valid.

Defunct 

The target no longer exists.

UnknownError 

The value could not be written, but the reason is unknown.

Constructor & Destructor Documentation

◆ WriteHandle() [1/8]

xentara::data::WriteHandle::WriteHandle ( )

Default constructor.

This constructor creates a null handle that is not associated with any value. Reading the handle will always return make_error_code(Error::NullHandle).

◆ WriteHandle() [2/8]

xentara::data::WriteHandle::WriteHandle ( Error  error)

Constructor for an error handle that always returns a write error.

This constructor creates a handle that always returns a certain error when attempting to write. Writing the handle will always return make_error_code(error).

Parameters
errorThe error the handle should return when attempting to write to it.

◆ WriteHandle() [3/8]

xentara::data::WriteHandle::WriteHandle ( std::error_code  error)

Constructor for an error handle that returns an arbitrary std::error_code.

This constructor creates a handle that always returns a certain error when attempting to write. Reading the handle will always return the given error.

Parameters
errorThe error code the handle should return when attempting to write to it.

◆ WriteHandle() [4/8]

template<memory::ObjectBlockType MemoryBlock>
xentara::data::WriteHandle::WriteHandle ( const std::shared_ptr< MemoryBlock > &  memoryBlock)

Constructor for a handle that writes to a memory block.

This function only stores a weak pointer to the memory block. If the weak pointer has expired (lock() returns nullptr) when a value is written, then write() will return Error::Defunct.

Parameters
memoryBlockA pointer to the memory block that sould be written. You can use the aliasing constructor (8) of std::shared_ptr or skill::EnableSharedFromThis::sharedFromThis<Alias>() to create a shared pointer to the memory block from a shared pointer to the enclosing object.

◆ WriteHandle() [5/8]

template<memory::ObjectBlockType MemoryBlock>
xentara::data::WriteHandle::WriteHandle ( const std::weak_ptr< MemoryBlock > &  memoryBlock)

Constructor for a handle that writes to a memory block.

If the weak pointer has expired (lock() returns nullptr) when a value is written, then write() will return Error::Defunct.

Parameters
memoryBlockA pointer to the memory block that sould be written.

◆ WriteHandle() [6/8]

template<typename Type , typename Callback >
requires std::is_invocable_v<const Callback &, Type &&>
xentara::data::WriteHandle::WriteHandle ( std::in_place_type_t< Type >  ,
Callback &&  callback 
)

Constructor for a handle that writes using a callback.

This constructor construct a handler that uses a callback to write the value. The callback will be called as if by:

std::invoke(std::as_const(callback), std::move(value));
T as_const(T... args)
T invoke(T... args)

Where value is the value, converted to Type.

The return value of the callback will be handled as follows:

  1. If the callback returns void, then write() will always return std::error_code().
  2. If the return value can be converted to an std::error_code, then write() will return that error code.
  3. If the return value can be converted to bool, then write() will return std::error_code() if the callback returns true, or Error::IllegalValue if the callback returns false.

Other return types are not allowed.

Examples:

auto myCallback(const Type &value) -> void;
auto myCallback(Type &&value) -> void;
auto myCallback(Type value) -> void;
auto myCallback(const Type &value) -> std::error_code;
auto myCallback(Type &&value) -> std::error_code;
auto myCallback(Type value) -> std::error_code;
auto myCallback(const Type &value) -> bool;
auto myCallback(Type &&value) -> bool;
auto myCallback(Type value) -> bool;

The callback may throw exceptions. If the callback throws an exception derived from std::system_error, write() will return the contained error code. If the callback throws another type of exception, write() will return Error::Unknown.

Parameters
callbackThe callback that should be called to handle the written value

◆ WriteHandle() [7/8]

template<typename Type , typename Object , typename Callback >
requires std::is_invocable_v<const Callback &, Object &, Type &&>
xentara::data::WriteHandle::WriteHandle ( std::in_place_type_t< Type >  ,
Callback &&  callback,
const std::shared_ptr< Object > &  object 
)

Constructor for a handle that writes by calling a callback with an object.

This constructor construct a handler that uses a member function as a callback to write the value. The callback will be called as if by:

std::invoke(std::as_const(callback), *object.get(), std::move(value));

Where value is the value, converted to Type.

This function only stores a weak pointer to the memory block. If the weak pointer has expired (lock() returns nullptr) when a value is written, then write() will return Error::Defunct.

The return value of the callback will be handled as follows:

  1. If the callback returns void, then write() will always return std::error_code().
  2. If the return value can be converted to an std::error_code, then write() will return that error code.
  3. If the return value can be converted to bool, then write() will return std::error_code() if the callback returns true, or Error::IllegalValue if the callback returns false.

Other return types are not allowed.

Examples:

auto Object::myCallback(const Type &value) -> void;
auto Object::myCallback(Type &&value) -> void;
auto Object::myCallback(Type value) -> void;
auto Object::myCallback(const Type &value) -> std::error_code;
auto Object::myCallback(Type &&value) -> std::error_code;
auto Object::myCallback(Type value) -> std::error_code;
auto Object::myCallback(const Type &value) -> bool;
auto Object::myCallback(Type &&value) -> bool;
auto Object::myCallback(Type value) -> bool;

The callback may throw exceptions. If the callback throws an exception derived from std::system_error, write() will return the contained error code. If the callback throws another type of exception, write() will return Error::Unknown.

Parameters
callbackThe callback that should be called to handle the written value
objectThe object that should be passed to the callback

◆ WriteHandle() [8/8]

template<typename Type , typename Object , typename Callback >
requires std::is_invocable_v<const Callback &, Object &, Type &&>
xentara::data::WriteHandle::WriteHandle ( std::in_place_type_t< Type >  ,
Callback &&  callback,
const std::weak_ptr< Object > &  object 
)

Constructor for a handle that writes by calling a callback with an object.

This constructor construct a handler that uses a member function as a callback to write the value. The callback will be called as if by:

std::invoke(std::as_const(callback), *object.lock(), value);

Where value is the value as a const Type &. If the weak pointer has expired (lock() returns nullptr) when a value is written, then write() will return Error::Defunct.

The return value of the callback will be handled as follows:

  1. If the callback returns void, then write() will always return std::error_code().
  2. If the return value can be converted to an std::error_code, then write() will return that error code.
  3. If the return value can be converted to bool, then write() will return std::error_code() if the callback returns true, or Error::IllegalValue if the callback returns false.

Other return types are not allowed.

Examples:

auto Object::myCallback(const Type &value) -> void;
auto Object::myCallback(Type &&value) -> void;
auto Object::myCallback(Type value) -> void;
auto Object::myCallback(const Type &value) -> std::error_code;
auto Object::myCallback(Type &&value) -> std::error_code;
auto Object::myCallback(Type value) -> std::error_code;
auto Object::myCallback(const Type &value) -> bool;
auto Object::myCallback(Type &&value) -> bool;
auto Object::myCallback(Type value) -> bool;

The callback may throw exceptions. If the callback throws an exception derived from std::system_error, write() will return the contained error code. If the callback throws another type of exception, write() will return Error::Unknown.

Parameters
callbackThe callback that should be called to handle the written value
objectThe object that should be passed to the callback

Member Function Documentation

◆ bitSize()

auto xentara::data::WriteHandle::bitSize ( ) const -> int
noexcept

Gets the number of bits that a numeric handle supports.

This function can be used to determine how many bits a handle supports. The meaning of the bit size depends on the native type:

  • for NativeType::Boolean, the bit size is always 1.
  • for NativeType::Integer, the bit size is the number of bits the integer uses, including the sign bit. For example, for a 32-bit signed integer, the bit size is 32 (31 significant bits + one sign bit).
  • for NativeType::UnsignedInteger, the bit size is the number of bits the integer uses. For example, for a 32-bit signed integer, the bit size is 32.
  • For NativeType::FloatingPoint, the bit size is the size of all bits used by the type, including mantissa, exponent, and sign bits. For example, for a double precision IEEE floating point number, the bit size is 64.
  • For all other types, the function returns 0.
    Returns
    The number of supported numeric bits, or 0 for non-numeric handles (including error handles).

◆ copy()

auto xentara::data::WriteHandle::copy ( const ReadHandle readHandle) const -> std::error_code

Copies a value from a read handle to a write handle.

This function can be used to transfer the value from a read handle to a write handle without knowing what the type of the value is. The value will be automatically converted from the type stored in the read handle to the type used by the target of the write handle, if necessary. If the value cannot be converted, the function will return Error::TypeMismatch.

Parameters
readHandleThe read handle to copy the value from.
Returns
std::error_code() on success, or an error code if an error occurred. Please note that a return value of std::error_code() does not mean that the value was written successfully to the device. It only means that the handle was valid, and that any preliminary checks on the value, like range checking, succeeded.

◆ errorCategory()

static auto xentara::data::WriteHandle::errorCategory ( ) -> const std::error_category &
static

Gets the error category for error codes of type [Error].

◆ hardError()

auto xentara::data::WriteHandle::hardError ( ) const -> std::error_code

Gets the error of an error handle.

This function returns the error code of an error handle created using WriteHandle(Error error) or WriteHandle(const std::error_code &error). An error handle will always return the given error when calling write().

Soft errors, meaning errors that might go away at some point, can only be detected by attempting to write a value using write().

Returns
The hard error stored in the handle, or std::error_code() if this is not an error handle

◆ nativeType()

auto xentara::data::WriteHandle::nativeType ( ) const -> NativeType
noexcept

Gets the native type of the handle.

This function can be used to determine what is the best type is to use as a template parameter for the write() function. You can use this function if you want to treat certain data types separately, and not rely on the built-in conversions. For example, you can use this function if you want to normally write the value as a string, but handle numbers and Booleans differently.

Returns
A hint as to which type would be best suited to supply the value to write. For error handles, NativeType::None is returned.

◆ operator==() [1/2]

auto xentara::data::WriteHandle::operator== ( const std::error_code error) const -> bool

Checks whether the handle is an error handle that returns a certain error.

This operator checks whether the handle is an error handle created using WriteHandle(const std::error_code &error) or WriteHandle(Error error). An error handle will always return the given error when calling read(), and will never return a valid value.

Soft errors, meaning errors that might go away at some point, can only be gotten using read().

Returns
Returns true if the handle is an error handle and the stored error matches error.

◆ operator==() [2/2]

auto xentara::data::WriteHandle::operator== ( Error  error) const -> bool

Checks whether the handle is an error handle that returns a certain error.

This function returns the error code of an error handle created using WriteHandle(Error error) or WriteHandle(const std::error_code &error). An error handle will always return the given error when calling write().

Soft errors, meaning errors that might go away at some point, can only be detected by attempting to write a value using write().

Returns
Returns true if the handle is an error handle and the stored error matches error.

◆ typeId()

auto xentara::data::WriteHandle::typeId ( ) const -> const std::type_info &
noexcept

Gets the precise type ID of the internal type used by the handle.

This function can be used to check what the exact internal type used by the handle is. Wjile this function will work for any type of handle, generally it should only be used for handles with [native type](nativeType()] NativeType::Custom. For other types, the results may be misleading. Checking whether a handle uses a 32-bit signed integral type by checking whether this function returns typeid(std::uint32_t), for example, will not work, because there may be multiple distinct 32-bit unsigned integer types. Under Windows, for example, both unsigned int and unsigned long are 32 bit unsigned integers, but they have different type IDs. Under 64-bit Linux, the same goes for unsigned long and unsigned long long, which are both 64-bit unsigned integer types.

Returns
The type ID of the internal type used by the handle. For error handles, a type ID for a dummy type is returned.

◆ write()

template<typename Type >
auto xentara::data::WriteHandle::write ( Type &&  value) const -> std::error_code

Writes a value.

The value will be converted to the type used by the target, if possible. If the value cannot be converted, the function will return Error::TypeMismatch.

If Type is std::any, and the std::any object contains one of the canonical read type of one of the NativeType enumeration values, then this function will attempt to extract that type and convert it to the target type if necessary. This allows you to pass an std::any object returned by ReadHandle::read<std::any>() to this function, and an appropriate conversion will be performed.

To transfer a value from a read handle to a write handle, is is not necessary to use an intermediate std::any object. Instead, you can transfer the value directly and efficiently using copy().

Returns
std::error_code() on success, or an error code if an error occurred. Please note that a return value of std::error_code() does not mean that the value was written successfully to the device. It only means that the handle was valid, and that any preliminary checks on the value, like range checking, succeeded.