+/*!
+@defgroup api-val Values
+
+@brief
+ Generic, JSON-like basic data containers.
+
+<strong><em>Values</em></strong> are generic data containers. Except for
+the fact that integer values are explicitly unsigned or signed because
+of typing limitations,
+\bt_name values are very similar to <a href="https://json.org/">JSON</a>
+values.
+
+The value API is completely independent from the rest of the
+\bt_api.
+
+\bt_c_comp initialization parameters, \ref bt_query_executor_create()
+"query" parameters, as well as trace IR user attributes (for example,
+bt_event_class_set_user_attributes()) use values.
+
+The available value types are:
+
+<dl>
+ <dt>Scalar values</dt>
+ <dd>
+ - Null
+ - Boolean
+ - Unsigned integer (64-bit range)
+ - Signed integer (64-bit range)
+ - Real (\c double range)
+ - String
+ </dd>
+
+ <dt>Container values</dt>
+ <dd>
+ - Array
+ - Map (string to value)
+ </dd>
+</dl>
+
+Values are \ref api-fund-shared-object "shared objects": get a new
+reference with bt_value_get_ref() and put an existing reference with
+bt_value_put_ref().
+
+Some library functions \ref api-fund-freezing "freeze" values on
+success. The documentation of those functions indicate this
+postcondition.
+
+All the value types share the same C type, #bt_value.
+
+Get the type enumerator of a value with bt_value_get_type(). Get whether
+or not a value type conceptually \em is a given type with the inline
+bt_value_type_is() function. Get whether or not a value has a specific
+type with one of the <code>bt_value_is_*()</code> inline helpers.
+
+The \em null value is special in that it's a singleton variable,
+#bt_value_null. You can directly compare any value pointer to
+#bt_value_null to check if it's a null value. Like other types of
+values, the null value is a shared object: if you get a new null value
+reference, you must eventually put it.
+
+Create a value with one of the <code>bt_value_*_create()</code> or
+<code>bt_value_*_create_init()</code> functions.
+
+This documentation names the actual data that a scalar value wraps the
+<em>raw value</em>.
+
+Set and get the raw values of scalar values with functions that are
+named <code>bt_value_*_set()</code> and <code>bt_value_*_get()</code>.
+
+Check that two values are recursively equal with bt_value_is_equal().
+
+Deep-copy a value with bt_value_copy().
+
+Extend a map value with bt_value_map_extend().
+
+The following table shows the available functions and types for each
+type of value:
+
+<table>
+ <tr>
+ <th>Name
+ <th>Type enumerator
+ <th>Type query function
+ <th>Creation functions
+ <th>Writing functions
+ <th>Reading functions
+ <tr>
+ <th>\em Null
+ <td>#BT_VALUE_TYPE_NULL
+ <td>bt_value_is_null()
+ <td>\em N/A (use the #bt_value_null variable directly)
+ <td>\em N/A
+ <td>\em N/A
+ <tr>
+ <th>\em Boolean
+ <td>#BT_VALUE_TYPE_BOOL
+ <td>bt_value_is_bool()
+ <td>
+ bt_value_bool_create()<br>
+ bt_value_bool_create_init()
+ <td>bt_value_bool_set()
+ <td>bt_value_bool_get()
+ <tr>
+ <th><em>Unsigned integer</em>
+ <td>#BT_VALUE_TYPE_UNSIGNED_INTEGER
+ <td>bt_value_is_unsigned_integer()
+ <td>
+ bt_value_integer_unsigned_create()<br>
+ bt_value_integer_unsigned_create_init()
+ <td>bt_value_integer_unsigned_set()
+ <td>bt_value_integer_unsigned_get()
+ <tr>
+ <th><em>Signed integer</em>
+ <td>#BT_VALUE_TYPE_SIGNED_INTEGER
+ <td>bt_value_is_signed_integer()
+ <td>
+ bt_value_integer_signed_create()<br>
+ bt_value_integer_signed_create_init()
+ <td>bt_value_integer_signed_set()
+ <td>bt_value_integer_signed_get()
+ <tr>
+ <th>\em Real
+ <td>#BT_VALUE_TYPE_REAL
+ <td>bt_value_is_real()
+ <td>
+ bt_value_real_create()<br>
+ bt_value_real_create_init()
+ <td>bt_value_real_set()
+ <td>bt_value_real_get()
+ <tr>
+ <th>\em String
+ <td>#BT_VALUE_TYPE_STRING
+ <td>bt_value_is_string()
+ <td>
+ bt_value_string_create()<br>
+ bt_value_string_create_init()
+ <td>bt_value_string_set()
+ <td>bt_value_string_get()
+ <tr>
+ <th>\em Array
+ <td>#BT_VALUE_TYPE_ARRAY
+ <td>bt_value_is_array()
+ <td>
+ bt_value_array_create()
+ <td>
+ bt_value_array_append_element()<br>
+ bt_value_array_append_bool_element()<br>
+ bt_value_array_append_unsigned_integer_element()<br>
+ bt_value_array_append_signed_integer_element()<br>
+ bt_value_array_append_real_element()<br>
+ bt_value_array_append_string_element()<br>
+ bt_value_array_append_empty_array_element()<br>
+ bt_value_array_append_empty_map_element()<br>
+ bt_value_array_set_element_by_index()
+ <td>
+ bt_value_array_get_length()<br>
+ bt_value_array_is_empty()<br>
+ bt_value_array_borrow_element_by_index()<br>
+ bt_value_array_borrow_element_by_index_const()
+ <tr>
+ <th>\em Map
+ <td>#BT_VALUE_TYPE_MAP
+ <td>bt_value_is_map()
+ <td>
+ bt_value_map_create()
+ <td>
+ bt_value_map_insert_entry()<br>
+ bt_value_map_insert_bool_entry()<br>
+ bt_value_map_insert_unsigned_integer_entry()<br>
+ bt_value_map_insert_signed_integer_entry()<br>
+ bt_value_map_insert_real_entry()<br>
+ bt_value_map_insert_string_entry()<br>
+ bt_value_map_insert_empty_array_entry()<br>
+ bt_value_map_insert_empty_map_entry()<br>
+ bt_value_map_extend()
+ <td>
+ bt_value_map_get_size()<br>
+ bt_value_map_is_empty()<br>
+ bt_value_map_has_entry()<br>
+ bt_value_map_borrow_entry_value()<br>
+ bt_value_map_borrow_entry_value_const()<br>
+ bt_value_map_foreach_entry()<br>
+ bt_value_map_foreach_entry_const()
+</table>
+*/
+
+/*! @{ */
+
+/*!
+@name Type
+@{
+
+@typedef struct bt_value bt_value;
+
+@brief
+ Value.
+
+@}
+*/
+
+/*!
+@name Type query
+@{
+*/
+
+/*!
+@brief
+ Value type enumerators.
+*/
+typedef enum bt_value_type {
+ /*!
+ @brief
+ Null value.
+ */
+ BT_VALUE_TYPE_NULL = 1 << 0,
+
+ /*!
+ @brief
+ Boolean value.
+ */
+ BT_VALUE_TYPE_BOOL = 1 << 1,
+
+ /*!
+ @brief
+ Integer value.
+
+ No value has this type: use it with bt_value_type_is().
+ */
+ BT_VALUE_TYPE_INTEGER = 1 << 2,
+
+ /*!
+ @brief
+ Unsigned integer value.
+
+ This type conceptually inherits #BT_VALUE_TYPE_INTEGER.
+ */
+ BT_VALUE_TYPE_UNSIGNED_INTEGER = (1 << 3) | BT_VALUE_TYPE_INTEGER,
+
+ /*!
+ @brief
+ Signed integer value.
+
+ This type conceptually inherits #BT_VALUE_TYPE_INTEGER.
+ */
+ BT_VALUE_TYPE_SIGNED_INTEGER = (1 << 4) | BT_VALUE_TYPE_INTEGER,
+
+ /*!
+ @brief
+ Real value.
+ */
+ BT_VALUE_TYPE_REAL = 1 << 5,
+
+ /*!
+ @brief
+ String value.
+ */
+ BT_VALUE_TYPE_STRING = 1 << 6,
+
+ /*!
+ @brief
+ Array value.
+ */
+ BT_VALUE_TYPE_ARRAY = 1 << 7,
+
+ /*!
+ @brief
+ Map value.
+ */
+ BT_VALUE_TYPE_MAP = 1 << 8,
+} bt_value_type;
+
+/*!
+@brief
+ Returns the type enumerator of the value \bt_p{value}.
+
+@param[in] value
+ Value of which to get the type enumerator
+
+@returns
+ Type enumerator of \bt_p{value}.
+
+@bt_pre_not_null{value}
+
+@sa bt_value_type_is() —
+ Returns whether or not the type of a value conceptually is a given
+ type.
+@sa bt_value_is_null() —
+ Returns whether or not a value is a null value.
+@sa bt_value_is_bool() —
+ Returns whether or not a value is a boolean value.
+@sa bt_value_is_unsigned_integer() —
+ Returns whether or not a value is an unsigned integer value.
+@sa bt_value_is_signed_integer() —
+ Returns whether or not a value is a signed integer value.
+@sa bt_value_is_real() —
+ Returns whether or not a value is a real value.
+@sa bt_value_is_string() —
+ Returns whether or not a value is a string value.
+@sa bt_value_is_array() —
+ Returns whether or not a value is an array value.
+@sa bt_value_is_map() —
+ Returns whether or not a value is a map value.
+*/
+extern bt_value_type bt_value_get_type(const bt_value *value) __BT_NOEXCEPT;
+
+/*!
+@brief
+ Returns whether or not the value type \bt_p{type} conceptually
+ \em is the value type \bt_p{other_type}.
+
+For example, an unsigned integer value conceptually \em is an integer
+value, so
+
+@code
+bt_value_type_is(BT_VALUE_TYPE_UNSIGNED_INTEGER, BT_VALUE_TYPE_INTEGER)
+@endcode
+
+returns #BT_TRUE.
+
+@param[in] type
+ Value type to check against \bt_p{other_type}.
+@param[in] other_type
+ Value type against which to check \bt_p{type}.
+
+@returns
+ #BT_TRUE if \bt_p{type} conceptually \em is \bt_p{other_type}.
+
+@sa bt_value_get_type() —
+ Returns the type enumerator of a value.
+@sa bt_value_is_null() —
+ Returns whether or not a value is a null value.
+@sa bt_value_is_bool() —
+ Returns whether or not a value is a boolean value.
+@sa bt_value_is_unsigned_integer() —
+ Returns whether or not a value is an unsigned integer value.
+@sa bt_value_is_signed_integer() —
+ Returns whether or not a value is a signed integer value.
+@sa bt_value_is_real() —
+ Returns whether or not a value is a real value.
+@sa bt_value_is_string() —
+ Returns whether or not a value is a string value.
+@sa bt_value_is_array() —
+ Returns whether or not a value is an array value.
+@sa bt_value_is_map() —
+ Returns whether or not a value is a map value.
+*/
+static inline
+bt_bool bt_value_type_is(const bt_value_type type,
+ const bt_value_type other_type) __BT_NOEXCEPT
+{
+ return (type & other_type) == other_type;
+}
+
+/*!
+@brief
+ Returns whether or not the value \bt_p{value} is a null value.
+
+@note
+ Because all null values point to the same null value singleton, you
+ can also directly compare \bt_p{value} to the #bt_value_null
+ variable.
+
+@param[in] value
+ Value to check.
+
+@returns
+ #BT_TRUE if \bt_p{value} is a null value.
+
+@bt_pre_not_null{value}
+
+@sa bt_value_get_type() —
+ Returns the type enumerator of a value.
+@sa bt_value_type_is() —
+ Returns whether or not the type of a value conceptually is a given
+ type.
+@sa #bt_value_null —
+ The null value singleton.
+*/
+static inline
+bt_bool bt_value_is_null(const bt_value *value) __BT_NOEXCEPT
+{
+ return bt_value_get_type(value) == BT_VALUE_TYPE_NULL;
+}
+
+/*!
+@brief
+ Returns whether or not the value \bt_p{value} is a boolean value.
+
+@param[in] value
+ Value to check.
+
+@returns
+ #BT_TRUE if \bt_p{value} is a boolean value.
+
+@bt_pre_not_null{value}
+
+@sa bt_value_get_type() —
+ Returns the type enumerator of a value.
+@sa bt_value_type_is() —
+ Returns whether or not the type of a value conceptually is a given
+ type.
+*/
+static inline
+bt_bool bt_value_is_bool(const bt_value *value) __BT_NOEXCEPT
+{
+ return bt_value_get_type(value) == BT_VALUE_TYPE_BOOL;
+}
+
+/*!
+@brief
+ Returns whether or not the value \bt_p{value} is an unsigned integer
+ value.
+
+@param[in] value
+ Value to check.
+
+@returns
+ #BT_TRUE if \bt_p{value} is an unsigned integer value.
+
+@bt_pre_not_null{value}
+
+@sa bt_value_get_type() —
+ Returns the type enumerator of a value.
+@sa bt_value_type_is() —
+ Returns whether or not the type of a value conceptually is a given
+ type.
+*/
+static inline
+bt_bool bt_value_is_unsigned_integer(const bt_value *value) __BT_NOEXCEPT
+{
+ return bt_value_get_type(value) == BT_VALUE_TYPE_UNSIGNED_INTEGER;
+}
+
+/*!
+@brief
+ Returns whether or not the value \bt_p{value} is a signed integer
+ value.
+
+@param[in] value
+ Value to check.
+
+@returns
+ #BT_TRUE if \bt_p{value} is a signed integer value.
+
+@bt_pre_not_null{value}
+
+@sa bt_value_get_type() —
+ Returns the type enumerator of a value.
+@sa bt_value_type_is() —
+ Returns whether or not the type of a value conceptually is a given
+ type.
+*/
+static inline
+bt_bool bt_value_is_signed_integer(const bt_value *value) __BT_NOEXCEPT
+{
+ return bt_value_get_type(value) == BT_VALUE_TYPE_SIGNED_INTEGER;
+}
+
+/*!
+@brief
+ Returns whether or not the value \bt_p{value} is a real value.
+
+@param[in] value
+ Value to check.
+
+@returns
+ #BT_TRUE if \bt_p{value} is a real value.
+
+@bt_pre_not_null{value}
+
+@sa bt_value_get_type() —
+ Returns the type enumerator of a value.
+@sa bt_value_type_is() —
+ Returns whether or not the type of a value conceptually is a given
+ type.
+*/
+static inline
+bt_bool bt_value_is_real(const bt_value *value) __BT_NOEXCEPT
+{
+ return bt_value_get_type(value) == BT_VALUE_TYPE_REAL;
+}
+
+/*!
+@brief
+ Returns whether or not the value \bt_p{value} is a string value.
+
+@param[in] value
+ Value to check.
+
+@returns
+ #BT_TRUE if \bt_p{value} is a string value.
+
+@bt_pre_not_null{value}
+
+@sa bt_value_get_type() —
+ Returns the type enumerator of a value.
+@sa bt_value_type_is() —
+ Returns whether or not the type of a value conceptually is a given
+ type.
+*/
+static inline
+bt_bool bt_value_is_string(const bt_value *value) __BT_NOEXCEPT
+{
+ return bt_value_get_type(value) == BT_VALUE_TYPE_STRING;
+}
+
+/*!
+@brief
+ Returns whether or not the value \bt_p{value} is an array value.
+
+@param[in] value
+ Value to check.
+
+@returns
+ #BT_TRUE if \bt_p{value} is an array value.
+
+@bt_pre_not_null{value}
+
+@sa bt_value_get_type() —
+ Returns the type enumerator of a value.
+@sa bt_value_type_is() —
+ Returns whether or not the type of a value conceptually is a given
+ type.
+*/
+static inline
+bt_bool bt_value_is_array(const bt_value *value) __BT_NOEXCEPT
+{
+ return bt_value_get_type(value) == BT_VALUE_TYPE_ARRAY;
+}
+
+/*!
+@brief
+ Returns whether or not the value \bt_p{value} is a map value.
+
+@param[in] value
+ Value to check.
+
+@returns
+ #BT_TRUE if \bt_p{value} is a map value.
+
+@bt_pre_not_null{value}
+
+@sa bt_value_get_type() —
+ Returns the type enumerator of a value.
+@sa bt_value_type_is() —
+ Returns whether or not the type of a value conceptually is a given
+ type.
+*/
+static inline
+bt_bool bt_value_is_map(const bt_value *value) __BT_NOEXCEPT
+{
+ return bt_value_get_type(value) == BT_VALUE_TYPE_MAP;
+}
+
+/*! @} */
+
+/*!
+@name Null value
+@{
+*/
+
+/*!
+@brief
+ The null value singleton.
+
+This is the \em only instance of a null value.
+
+Like any type of value, the null value is a shared object: if you get a
+new null value reference with bt_value_get_ref(), you must eventually
+put it with bt_value_put_ref(). The null value singleton's reference
+count must never reach 0: libbabeltrace2 logs a warning message when
+this programming error occurs.
+
+Because all null values point to the same null value singleton, you can
+directly compare a value to the \c bt_value_null variable.
+
+@attention
+ @parblock
+ \c bt_value_null is different from \c NULL: the former is a true
+ \bt_name value object while the latter is a C definition which
+ usually means "no pointer".
+
+ For example, bt_value_map_borrow_entry_value() can return
+ \c bt_value_null if the requested key is mapped to a null value, but
+ it can also return \c NULL if the key is not found.
+ @endparblock
+
+@sa bt_value_is_null() —
+ Returns whether or not a value is a null value.
+*/