[28/36] libcamera: value_node: Add mutable children accessors
diff mbox series

Message ID 20260113000808.15395-29-laurent.pinchart@ideasonboard.com
State New
Headers show
Series
  • libcamera: Global configuration file improvements
Related show

Commit Message

Laurent Pinchart Jan. 13, 2026, 12:08 a.m. UTC
At two at() functions that return mutable pointer to child nodes, based
on an index for lists and a key for dictionaries.

The API differs from const children accessors that use operator[] and
return a reference in order to allow better error handling: while the
const accessors return a reference to a global instance of an empty
ValueNode when the requested child doesn't exist, a mutable accessor
can't do the same without allowing modifying the empty global instance.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 include/libcamera/internal/value_node.h |  2 ++
 src/libcamera/value_node.cpp            | 41 +++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

Comments

Barnabás Pőcze Jan. 14, 2026, 9:52 a.m. UTC | #1
2026. 01. 13. 1:08 keltezéssel, Laurent Pinchart írta:
> At two at() functions that return mutable pointer to child nodes, based
   Add


> on an index for lists and a key for dictionaries.
> 
> The API differs from const children accessors that use operator[] and
> return a reference in order to allow better error handling: while the
> const accessors return a reference to a global instance of an empty
> ValueNode when the requested child doesn't exist, a mutable accessor
> can't do the same without allowing modifying the empty global instance.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>   include/libcamera/internal/value_node.h |  2 ++
>   src/libcamera/value_node.cpp            | 41 +++++++++++++++++++++++++
>   2 files changed, 43 insertions(+)
> 
> diff --git a/include/libcamera/internal/value_node.h b/include/libcamera/internal/value_node.h
> index 56d200e1cf27..c285be4957ed 100644
> --- a/include/libcamera/internal/value_node.h
> +++ b/include/libcamera/internal/value_node.h
> @@ -228,9 +228,11 @@ public:
>   	ConstDictAdapter asDict() const { return ConstDictAdapter{ list_ }; }
>   	ConstListAdapter asList() const { return ConstListAdapter{ list_ }; }
>   
> +	ValueNode *at(std::size_t index);
>   	const ValueNode &operator[](std::size_t index) const;
>   
>   	bool contains(std::string_view key) const;
> +	ValueNode *at(std::string_view key);
>   	const ValueNode &operator[](std::string_view key) const;
>   
>   	ValueNode *add(std::unique_ptr<ValueNode> child);
> diff --git a/src/libcamera/value_node.cpp b/src/libcamera/value_node.cpp
> index 3c56b47bf79d..50b23284f930 100644
> --- a/src/libcamera/value_node.cpp
> +++ b/src/libcamera/value_node.cpp
> @@ -384,6 +384,24 @@ template struct ValueNode::Accessor<std::vector<std::string>>;
>    * \return An adapter of unspecified type compatible with range-based for loops
>    */
>   
> +/**
> + * \brief Retrieve the element from list ValueNode by index
> + * \param[in] index The element index
> + *
> + * This function retrieves an element of the ValueNode. Only ValueNode
> + * instances of List type associate elements with index, calling this function
                                                      an index / indices ?


> + * on other types of instances or with an invalid index returns a null pointer.
> + *
> + * \return The ValueNode as an element of the list

I would write "The ValueNode corresponding to \a index".


Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>

> + */
> +ValueNode *ValueNode::at(std::size_t index)
> +{
> +	if (type_ != Type::List || index >= size())
> +		return nullptr;
> +
> +	return list_[index].value.get();
> +}
> +
>   /**
>    * \brief Retrieve the element from list ValueNode by index
>    * \param[in] index The element index
> @@ -419,6 +437,29 @@ bool ValueNode::contains(std::string_view key) const
>   	return dictionary_.find(key) != dictionary_.end();
>   }
>   
> +/**
> + * \brief Retrieve a member by key from the dictionary
> + * \param[in] key The element key
> + *
> + * This function retrieves a member of a ValueNode by \a key. Only ValueNode
> + * instances of Dictionary type associate elements with keys, calling this
> + * function on other types of instances or with a nonexistent key returns a null
> + * pointer.
> + *
> + * \return The ValueNode corresponding to the \a key member
> + */
> +ValueNode *ValueNode::at(std::string_view key)
> +{
> +	if (type_ != Type::Dictionary)
> +		return nullptr;
> +
> +	auto iter = dictionary_.find(key);
> +	if (iter == dictionary_.end())
> +		return nullptr;
> +
> +	return iter->second;
> +}
> +
>   /**
>    * \brief Retrieve a member by key from the dictionary
>    * \param[in] key The element key
Laurent Pinchart Jan. 18, 2026, 11:20 p.m. UTC | #2
On Wed, Jan 14, 2026 at 10:52:13AM +0100, Barnabás Pőcze wrote:
> 2026. 01. 13. 1:08 keltezéssel, Laurent Pinchart írta:
> > At two at() functions that return mutable pointer to child nodes, based
>    Add
> 
> > on an index for lists and a key for dictionaries.
> > 
> > The API differs from const children accessors that use operator[] and
> > return a reference in order to allow better error handling: while the
> > const accessors return a reference to a global instance of an empty
> > ValueNode when the requested child doesn't exist, a mutable accessor
> > can't do the same without allowing modifying the empty global instance.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > ---
> >   include/libcamera/internal/value_node.h |  2 ++
> >   src/libcamera/value_node.cpp            | 41 +++++++++++++++++++++++++
> >   2 files changed, 43 insertions(+)
> > 
> > diff --git a/include/libcamera/internal/value_node.h b/include/libcamera/internal/value_node.h
> > index 56d200e1cf27..c285be4957ed 100644
> > --- a/include/libcamera/internal/value_node.h
> > +++ b/include/libcamera/internal/value_node.h
> > @@ -228,9 +228,11 @@ public:
> >   	ConstDictAdapter asDict() const { return ConstDictAdapter{ list_ }; }
> >   	ConstListAdapter asList() const { return ConstListAdapter{ list_ }; }
> >   
> > +	ValueNode *at(std::size_t index);
> >   	const ValueNode &operator[](std::size_t index) const;
> >   
> >   	bool contains(std::string_view key) const;
> > +	ValueNode *at(std::string_view key);
> >   	const ValueNode &operator[](std::string_view key) const;
> >   
> >   	ValueNode *add(std::unique_ptr<ValueNode> child);
> > diff --git a/src/libcamera/value_node.cpp b/src/libcamera/value_node.cpp
> > index 3c56b47bf79d..50b23284f930 100644
> > --- a/src/libcamera/value_node.cpp
> > +++ b/src/libcamera/value_node.cpp
> > @@ -384,6 +384,24 @@ template struct ValueNode::Accessor<std::vector<std::string>>;
> >    * \return An adapter of unspecified type compatible with range-based for loops
> >    */
> >   
> > +/**
> > + * \brief Retrieve the element from list ValueNode by index
> > + * \param[in] index The element index
> > + *
> > + * This function retrieves an element of the ValueNode. Only ValueNode
> > + * instances of List type associate elements with index, calling this function
>                                                       an index / indices ?

"an index" sounds good.

> > + * on other types of instances or with an invalid index returns a null pointer.
> > + *
> > + * \return The ValueNode as an element of the list
> 
> I would write "The ValueNode corresponding to \a index".

Ack, will address all three comments.

> Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
> 
> > + */
> > +ValueNode *ValueNode::at(std::size_t index)
> > +{
> > +	if (type_ != Type::List || index >= size())
> > +		return nullptr;
> > +
> > +	return list_[index].value.get();
> > +}
> > +
> >   /**
> >    * \brief Retrieve the element from list ValueNode by index
> >    * \param[in] index The element index
> > @@ -419,6 +437,29 @@ bool ValueNode::contains(std::string_view key) const
> >   	return dictionary_.find(key) != dictionary_.end();
> >   }
> >   
> > +/**
> > + * \brief Retrieve a member by key from the dictionary
> > + * \param[in] key The element key
> > + *
> > + * This function retrieves a member of a ValueNode by \a key. Only ValueNode
> > + * instances of Dictionary type associate elements with keys, calling this
> > + * function on other types of instances or with a nonexistent key returns a null
> > + * pointer.
> > + *
> > + * \return The ValueNode corresponding to the \a key member
> > + */
> > +ValueNode *ValueNode::at(std::string_view key)
> > +{
> > +	if (type_ != Type::Dictionary)
> > +		return nullptr;
> > +
> > +	auto iter = dictionary_.find(key);
> > +	if (iter == dictionary_.end())
> > +		return nullptr;
> > +
> > +	return iter->second;
> > +}
> > +
> >   /**
> >    * \brief Retrieve a member by key from the dictionary
> >    * \param[in] key The element key

Patch
diff mbox series

diff --git a/include/libcamera/internal/value_node.h b/include/libcamera/internal/value_node.h
index 56d200e1cf27..c285be4957ed 100644
--- a/include/libcamera/internal/value_node.h
+++ b/include/libcamera/internal/value_node.h
@@ -228,9 +228,11 @@  public:
 	ConstDictAdapter asDict() const { return ConstDictAdapter{ list_ }; }
 	ConstListAdapter asList() const { return ConstListAdapter{ list_ }; }
 
+	ValueNode *at(std::size_t index);
 	const ValueNode &operator[](std::size_t index) const;
 
 	bool contains(std::string_view key) const;
+	ValueNode *at(std::string_view key);
 	const ValueNode &operator[](std::string_view key) const;
 
 	ValueNode *add(std::unique_ptr<ValueNode> child);
diff --git a/src/libcamera/value_node.cpp b/src/libcamera/value_node.cpp
index 3c56b47bf79d..50b23284f930 100644
--- a/src/libcamera/value_node.cpp
+++ b/src/libcamera/value_node.cpp
@@ -384,6 +384,24 @@  template struct ValueNode::Accessor<std::vector<std::string>>;
  * \return An adapter of unspecified type compatible with range-based for loops
  */
 
+/**
+ * \brief Retrieve the element from list ValueNode by index
+ * \param[in] index The element index
+ *
+ * This function retrieves an element of the ValueNode. Only ValueNode
+ * instances of List type associate elements with index, calling this function
+ * on other types of instances or with an invalid index returns a null pointer.
+ *
+ * \return The ValueNode as an element of the list
+ */
+ValueNode *ValueNode::at(std::size_t index)
+{
+	if (type_ != Type::List || index >= size())
+		return nullptr;
+
+	return list_[index].value.get();
+}
+
 /**
  * \brief Retrieve the element from list ValueNode by index
  * \param[in] index The element index
@@ -419,6 +437,29 @@  bool ValueNode::contains(std::string_view key) const
 	return dictionary_.find(key) != dictionary_.end();
 }
 
+/**
+ * \brief Retrieve a member by key from the dictionary
+ * \param[in] key The element key
+ *
+ * This function retrieves a member of a ValueNode by \a key. Only ValueNode
+ * instances of Dictionary type associate elements with keys, calling this
+ * function on other types of instances or with a nonexistent key returns a null
+ * pointer.
+ *
+ * \return The ValueNode corresponding to the \a key member
+ */
+ValueNode *ValueNode::at(std::string_view key)
+{
+	if (type_ != Type::Dictionary)
+		return nullptr;
+
+	auto iter = dictionary_.find(key);
+	if (iter == dictionary_.end())
+		return nullptr;
+
+	return iter->second;
+}
+
 /**
  * \brief Retrieve a member by key from the dictionary
  * \param[in] key The element key