aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLexi Winter <lexi@hemlock.eden.le-fay.org>2025-03-29 02:26:49 +0000
committerLexi Winter <lexi@hemlock.eden.le-fay.org>2025-03-29 02:26:49 +0000
commit25cf4d9fe5b67e143cfaf2e8962c5f9e8e0828c1 (patch)
tree8bf4096950a988bd51210f5957752cdd7aa81fc1
parent328dfa4e2b718bff742f2c6d704393480fa711bd (diff)
downloadlibnvxx-25cf4d9fe5b67e143cfaf2e8962c5f9e8e0828c1.tar.gz
libnvxx-25cf4d9fe5b67e143cfaf2e8962c5f9e8e0828c1.tar.bz2
clean up constructor semantics
-rw-r--r--libnvxx/nv_list.cc23
-rw-r--r--libnvxx/nvxx.3127
-rw-r--r--libnvxx/nvxx.cc14
-rw-r--r--libnvxx/nvxx_base.h2
4 files changed, 106 insertions, 60 deletions
diff --git a/libnvxx/nv_list.cc b/libnvxx/nv_list.cc
index 6bcfd7e..98f2c93 100644
--- a/libnvxx/nv_list.cc
+++ b/libnvxx/nv_list.cc
@@ -15,29 +15,36 @@ namespace bsd {
*/
nv_list::nv_list(int flags)
- : __nv_list_base(flags)
+ : __nv_list_base(::nvlist_create(flags),
+ __detail::__nvlist_owning::__owning)
{
+ if (__m_nv == nullptr)
+ throw std::system_error(
+ std::error_code(errno, std::generic_category()));
}
-nv_list::nv_list(::nvlist_t *nvl) noexcept
+nv_list::nv_list(::nvlist_t *nvl)
: __nv_list_base(nvl, __detail::__nvlist_owning::__owning)
{
+ if (nvl == nullptr)
+ throw std::logic_error("attempt to create an nv_list from "
+ "a null pointer");
}
nv_list::nv_list(const_nv_list const &other)
- : __nv_list_base(::nvlist_clone(other.ptr()),
- __detail::__nvlist_owning::__owning)
+ : __nv_list_base(nullptr, __detail::__nvlist_owning::__owning)
{
+ if (auto err = other.error(); err)
+ throw nv_error_state(err);
+
+ __m_nv = ::nvlist_clone(other.ptr());
if (__m_nv == nullptr)
throw std::system_error(std::error_code(errno, std::system_category()));
}
nv_list::nv_list(nv_list const &other)
- : __nv_list_base(::nvlist_clone(other.__m_nv),
- __detail::__nvlist_owning::__owning)
+ : nv_list(static_cast<const_nv_list const &>(other))
{
- if (__m_nv == nullptr)
- throw std::system_error(std::error_code(errno, std::system_category()));
}
nv_list::nv_list(nv_list &&other) noexcept
diff --git a/libnvxx/nvxx.3 b/libnvxx/nvxx.3
index 73e880f..a5b1a43 100644
--- a/libnvxx/nvxx.3
+++ b/libnvxx/nvxx.3
@@ -295,14 +295,6 @@ A
.Vt const_nv_list
provides all non-mutating operations on the nvlist, such as testing for the
existence of a key, fetching a key, and packing or sending an nvlist.
-A
-.Vt const_nv_list
-can be constructed from an existing
-.Vt const nvlist_t * ,
-or from an
-.Vt nv_list ,
-or copy-constructed from another
-.Vt const_nv_list .
Because
.Vt const_nv_list
is non-owning, it always refers to an existing nvlist and will never destroy
@@ -313,34 +305,91 @@ An
provides all the operations that
.Vt const_nv_list
provides, plus additional mutating operations such as adding or removing keys.
+.Pp
+Both
+.Vt const_nv list
+and
+.Vt nv_list
+support default initialization, copy-initialization and exception-free
+move-initialization.
+.Sh CREATING AN NV_LIST
+A new
+.Vt nv_list
+can be created using the default constructor.
+This will create a new, empty
+.Vt nvlist_t
+using
+.Fn ::nvlist_create
+and take ownership of it.
+If the
+.Fa flags
+argument is non-zero, it will be passed to
+.Fn ::nvlist_create .
+If an error occurs while creating the nvlist, an exception of type
+.Vt std::system_error
+will be thrown.
+.Pp
An
.Vt nv_list
-can be constructed from an existing
-.Vt nvlist_t * ,
-in which case it will take ownership of the nvlist.
-It may also be copy-constructed from another
+can also be created by copying an existing
.Vt nv_list
or
-.Vt const_nv_list ,
-in which case it will duplicate the underlying list using
-.Xr nvlist_clone 3 ,
-and it may be default-constructed, in which case it will create a new nvlist
+.Vt const_nv_list
+object, which will clone the underlying
+.Vt nvlist_t
using
-.Xr nvlist_create 3 .
-To pass flags to
-.Xr nvlist_create 3 ,
-use the optional
-.Fa "int flags"
-argument to the constructor.
+.Fn ::nvlist_clone .
+If the nvlist being copied from is in the error state, an exception of type
+.Vt nv_error_state
+will be thrown.
+If an error occurs while cloning the list, an exception of type
+.Vt std::system_error
+will be thrown.
.Pp
-Both
-.Vt const_nv list
-and
+An
+.Vt nv_list
+can also be created by providing an existing
+.Vt nvlist_t *
+pointer, in which case the
.Vt nv_list
-support copy-initialization and exception-free move-initialization.
-In addition,
+will take ownership of the underlying list.
+This does not clone the original
+.Vt nvlist_t * .
+.Pp
+Finally, an
.Vt nv_list
-supports default-initialization.
+can be created by moving an existing
+.Vt nv_list ,
+which will transfer ownership of the underlying nvlist and leave the moved-from
+object in an empty state.
+An
+.Vt nv_list
+in an empty state may be assigned to or destroyed, but no other options are
+possible.
+.Sh CREATING A CONST_NV_LIST
+A
+.Vt const_nv_list
+can be created using the default constructor.
+The new
+.Vt const_nv_list
+will be empty; it may be assigned to or destroyed, but no other operation is
+possible.
+.Pp
+A
+.Vt const_nv_list
+can be implictly created from an existing
+.Vt nv_list
+object using the
+.Fn "nv_list::operator const_nv_list"
+member function.
+.Pp
+Finally, a
+.Vt const_nv_list
+can be created from an existing
+.Vt nvlist_t *
+pointer, or an
+.Vt nv_list
+object.
.Sh ERROR HANDLING
The library defines a base error class called
.Vt nv_error ,
@@ -553,7 +602,7 @@ If a value of the given name is already present in the nvlist, and the nvlist
does not permit duplicate value names, then an exception of type
.Vt nv_key_exists
is thrown, and the nvlist is placed in the error state.
-If the nvlist is in an error state, then an exception of type
+If the nvlist is already in an error state, then an exception of type
.Vt nv_error_state
is thrown, and the key is not added.
.Pp
@@ -566,7 +615,7 @@ prior to being added, and if later removed, will be closed using
.Xr close 2 .
The behaviour when attempting to add a duplicate value name is the same as
described for the other
-.Fn add_
+.Fn add_<type>
member functions.
.Pp
The
@@ -583,7 +632,7 @@ of the appropriate type; the value type of the span may be
.Vt const .
The behaviour when attempting to add a duplicate value name is the same as
described for the
-.Fn add_
+.Fn add_<type>
member functions.
.Pp
The
@@ -600,7 +649,7 @@ The value type of the range may be
.Vt const .
The behaviour when attempting to add a duplicate value name is the same as
described for the
-.Fn add_
+.Fn add_<type>
member functions.
.Pp
The
@@ -664,13 +713,13 @@ The
.Fn move_string
member function takes ownership of the provided string pointer, which must be a
NUL-terminated C string allocated using
-.Fn std::malloc ,
+.Xr malloc 3 .
and adds it to the nvlist.
The string will later be freed using
-.Fn std::free .
+.Xr free 3 .
The behaviour when attempting to add a duplicate value name is the same as
described for the
-.Fn add_
+.Fn add_<type>
member functions.
.Pp
The
@@ -679,7 +728,7 @@ member function takes ownership of the provided nvlist and adds it to the
nvlist.
The behaviour when attempting to add a duplicate value name is the same as
described for the
-.Fn add_
+.Fn add_<type>
member functions.
.Pp
The
@@ -700,13 +749,13 @@ and
member functions take ownership of the provided C array of the given type
and add it to the nvlist as an array.
The array must be a C array which was previously allocated using
-.Fn std::malloc .
+.Xr malloc 3 .
In the case of
.Fn move_string_array
and
.Fn move_nvlist_array ,
the nvlist takes ownership of the member values and will later free them using
-.Fn std::free
+.Xr free 3
(for strings) or
.Xr nvlist_destroy 3
(for nvlists).
@@ -805,3 +854,5 @@ a schema may also be passed directly to
.Fn nv_serialize
and
.Fn nv_deserialize .
+.Sh SEE ALSO
+.Xr nv 9
diff --git a/libnvxx/nvxx.cc b/libnvxx/nvxx.cc
index f567c47..2785aa0 100644
--- a/libnvxx/nvxx.cc
+++ b/libnvxx/nvxx.cc
@@ -14,22 +14,10 @@ namespace bsd::__detail {
* __nv_list_base
*/
-__nv_list_base::__nv_list_base(int flags)
- : __m_nv(::nvlist_create(flags))
- , __m_owning(__nvlist_owning::__owning)
-{
- if (__m_nv == nullptr)
- throw std::system_error(
- std::error_code(errno, std::generic_category()));
-}
-
__nv_list_base::__nv_list_base(nvlist_t *nv, __nvlist_owning owning)
: __m_nv(nv)
- , __m_owning(__nvlist_owning::__non_owning)
+ , __m_owning(owning)
{
- assert(nv);
- __throw_if_error();
- __m_owning = owning;
}
__nv_list_base::~__nv_list_base()
diff --git a/libnvxx/nvxx_base.h b/libnvxx/nvxx_base.h
index 0817f0a..bcf5012 100644
--- a/libnvxx/nvxx_base.h
+++ b/libnvxx/nvxx_base.h
@@ -354,7 +354,7 @@ struct nv_list final
/*
* Create an nv_list object that refers to an existing nvlist_t.
*/
- explicit nv_list(::nvlist_t *) noexcept;
+ explicit nv_list(::nvlist_t *);
/*
* Create an nv_list object by copying an existing const_nv_list object