Automation

Protocols are obviously quite similar, so the lfp:: namespace contains a few useful constructs that remove some boilerplate.

#include <lfp/protocol.hpp>

class unique_lfp

RAII for lfp_protocol

Some automation of the boilerplate when creating new protocols. Whenever a protocol only provides features on top of I/O, they must contain another lfp_protocol. The inner protocol should be tied to the lifetime of the outer layer, and std::unique_ptr is a perfect fit. However, since protocols are not cleaned up with delete, but rather with lfp_close(), a custom deleter is required.

Instances are implicitly convertible to lfp_protocol*, and support operator ->.

Public Functions

inline operator lfp_protocol*() noexcept(true)

Implicit conversion to lfp*

Implicitly convert to lfp*, so that unique_lfp objects can be passed directly to the lfp_* functions.

unique_lfp protocol(make_protocol());
std::int64_t offset;
auto err = lfp_tell(protocol, &offset);

inline operator const lfp_protocol*() const noexcept(true)

Implicit conversion to const lfp*

Implicitly convert to const lfp*, so that unique_lfp objects can be passed directly to the lfp_* functions.

unique_lfp protocol(make_protocol());
std::int64_t offset;
auto err = lfp_tell(protocol, &offset);

inline lfp_protocol *operator->() noexcept(true)

Forward -> to lfp

Call lfp methods directly on the unique_lfp handle.

unique_lfp protocol(make_protocol());
auto tell = protocol->tell();

inline const lfp_protocol *operator->() const noexcept(true)

Forward -> to lfp

Call lfp methods directly on the unique_lfp handle.

unique_lfp protocol(make_protocol());
auto tell = protocol->tell();

inline void close() noexcept(false)

Recursively close and release resources.

Release the underlying lfp_protocol* object, and set nullptr. This calls lfp_close(), and recursively releases lfp resources.

This method is not necessary to call, unless there is a desire to get the status code of the close operation. The destructor will clean it up otherwise.

inline lfp_protocol *release() noexcept(true)

Releases the pointer from unique_lfp ownership.

Underlying pointer is not destroyed, but its fate is no longer unique_lfp concern

inline lfp_protocol *get() const noexcept(true)

Return a pointer to the owned object.

The ownership is not released.

inline explicit operator bool() noexcept(true)

Conversion to bool

Checks whether an object is owned.

inline void *advance(void *p, std::ptrdiff_t n) noexcept(true)

Arithmetic for void pointers.

Automation for doing pointer arithetic on void pointers. C++, of course, does not allow arithmetic on void pointers, but lfp works on untyped bytes anyway. It is assumed that one increment means one byte/addressable unit, i.e. the behaviour of char*.

This does not behave like std::advance and modifies the pointer in-place - it returns a copy.

protocol->readinto(dst, 10, &nread);
dst = advance(dst, nread);

inline const void *advance(const void *p, std::ptrdiff_t n) noexcept(true)

Arithmetic for void pointers.

Automation for doing pointer arithetic on void pointers. C++, of course, does not allow arithmetic on void pointers, but lfp works on untyped bytes anyway. It is assumed that one increment means one byte/addressable unit, i.e. the behaviour of char*.

This does not behave like std::advance and modifies the pointer in-place - it returns a copy.

protocol->readinto(dst, 10, &nread);
dst = advance(dst, nread);