LCOV - code coverage report
Current view: top level - json - value_to.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 100.0 % 9 9
Test Date: 2026-07-10 12:38:05 Functions: 98.7 % 389 384 5

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3                 : // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
       4                 : // Copyright (c) 2022 Dmitry Arkhipov (grisumbras@gmail.com)
       5                 : //
       6                 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       7                 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       8                 : //
       9                 : // Official repository: https://github.com/boostorg/json
      10                 : //
      11                 : 
      12                 : #ifndef BOOST_JSON_VALUE_TO_HPP
      13                 : #define BOOST_JSON_VALUE_TO_HPP
      14                 : 
      15                 : #include <boost/core/detail/static_assert.hpp>
      16                 : #include <boost/json/detail/value_to.hpp>
      17                 : 
      18                 : namespace boost {
      19                 : namespace json {
      20                 : 
      21                 : /** Convert a @ref value to an object of type `T`.
      22                 : 
      23                 :     This function attempts to convert a @ref value to `T` using
      24                 : 
      25                 :     - one of @ref value's accessors, or
      26                 :     - a library-provided generic conversion, or
      27                 :     - a user-provided overload of `tag_invoke`.
      28                 : 
      29                 :     In order to perform the conversion the function selects an appropriate
      30                 :     implementation based on the types `T` and `Context` (if provided).
      31                 : 
      32                 :     1. If `Context` is available and is not `std::tuple<C...>`
      33                 : 
      34                 :        a. check if `use_category<T, Context>::value` is not
      35                 :           @ref conversion_category::unknown; otherwise
      36                 : 
      37                 :        b. check if a `tag_invoke` overload from the list below that takes a
      38                 :           `Context const&` exists.
      39                 : 
      40                 :     2. Otherwise, if `Context` is available, and is `std::tuple<C...>` repeat
      41                 :        steps **1** and **2** recursively for every `C` until either
      42                 :        step **1.a** or **1.b** succeeds for some `C`.
      43                 : 
      44                 :     3. Failing that,
      45                 : 
      46                 :        a. check if `use_category<T>::value` is not
      47                 :           @ref conversion_category::unknown; otherwise
      48                 : 
      49                 :        b. check if a `tag_invoke` overload from the list below that takes only
      50                 :           2 parameters exists; otherwise
      51                 : 
      52                 :        c. check if `T` is one of @ref value, @ref array, @ref object,
      53                 :           or @ref string; otherwise
      54                 : 
      55                 :        d. check if `T` matches one of the categories of types described in the
      56                 :           table "Conversion categories" in \<\<Value Conversion>> section.
      57                 : 
      58                 :     These steps determine both the appropriate category of conversion for `T`,
      59                 :     and, if necessary, the effective context `C` that will be used for
      60                 :     conversion. If the category is selected on steps **1.a**, **3.a**, **3.c**,
      61                 :     or **3.d**, the library provides a suitable conversion implementation.
      62                 :     If the category is selected on steps **2.b** or **3.b**, then a
      63                 :     user-provided `tag_invoke` overload is used.
      64                 : 
      65                 :     The overloads of `tag_invoke` that will be considered by this function
      66                 :     are in the following list. Overloads that appear higher in the list have
      67                 :     higher priority.
      68                 : 
      69                 :     @code
      70                 :     template< class FullContext >
      71                 :     result<T> tag_invoke( try_value_to_tag<T>, const value&, const Context&, const FullContext& );
      72                 : 
      73                 :     template< class FullContext >
      74                 :     T tag_invoke( value_to_tag<T>, const value&, const Context&, const FullContext& );
      75                 : 
      76                 :     result<T> tag_invoke( try_value_to_tag<T>, const value&, const Context& );
      77                 : 
      78                 :     T tag_invoke( value_to_tag<T>, const value&, const Context& );
      79                 : 
      80                 :     result<T> tag_invoke( try_value_to_tag<T>, const value& );
      81                 : 
      82                 :     T tag_invoke( value_to_tag<T>, const value& );
      83                 :     @endcode
      84                 : 
      85                 :     For `tag_invoke` overloads that take a parameter of type `value_to_tag<T>`
      86                 :     the object returned by a call to that overload is returned by the function
      87                 :     as the result of the conversion. For overloads that take a parameter of
      88                 :     type `try_value_to_tag<T>` if the returned `result` contains a value, that
      89                 :     value is returned as the result of the conversion. Otherwise, an exception
      90                 :     of type @ref boost::system::system_error that stores the error is thrown.
      91                 : 
      92                 :     The `ctx` argument can be used either as a tag type to provide conversions
      93                 :     for third-party types, or to pass extra data to the conversion function.
      94                 : 
      95                 :     Overload **(3)** is **deleted** and participates in overload resolution
      96                 :     only when `U` is not @ref value. The overload exists to prevent unintented
      97                 :     creation of temporary @ref value instances, e.g.
      98                 : 
      99                 :     @code
     100                 :     auto flag = value_to<bool>(true);
     101                 :     @endcode
     102                 : 
     103                 :     @par Constraints
     104                 :     @code
     105                 :     ! std::is_reference< T >::value
     106                 :     @endcode
     107                 : 
     108                 :     @par Exception Safety
     109                 :     Strong guarantee.
     110                 : 
     111                 :     @tparam T The type to convert to.
     112                 : 
     113                 :     @tparam Context The type of context passed to the conversion function.
     114                 : 
     115                 :     @returns `jv` converted to `T`.
     116                 : 
     117                 :     @param jv The @ref value to convert.
     118                 : 
     119                 :     @param ctx Context passed to the conversion function.
     120                 : 
     121                 :     @see @ref try_value_to, @ref value_from,
     122                 :     <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
     123                 :         tag_invoke: A general pattern for supporting customisable functions</a>
     124                 : 
     125                 :     @{
     126                 : */
     127                 : template< class T, class Context >
     128                 : T
     129 HIT         410 : value_to( value const& jv, Context const& ctx )
     130                 : {
     131                 :     BOOST_CORE_STATIC_ASSERT( ! std::is_reference<T>::value );
     132                 :     using bare_T = detail::remove_cvref<T>;
     133                 :     using cat = detail::value_to_category<Context, bare_T>;
     134             410 :     return detail::value_to_impl( cat(), value_to_tag<bare_T>(), jv, ctx );
     135                 : }
     136                 : 
     137                 : /// Overload
     138                 : template<class T>
     139                 : T
     140             131 : value_to(const value& jv)
     141                 : {
     142             192 :     return value_to<T>( jv, detail::no_context() );
     143                 : }
     144                 : 
     145                 : /// Overload
     146                 : template<class T, class U
     147                 : #ifndef BOOST_JSON_DOCS
     148                 :     , class = typename std::enable_if<!std::is_same<U, value>::value>::type
     149                 : #endif
     150                 : >
     151                 : T
     152                 : value_to(U const& jv) = delete;
     153                 : /// @}
     154                 : 
     155                 : /** Convert a @ref value to a @ref boost::system::result.
     156                 : 
     157                 :     This function attempts to convert a @ref value to `result<T>` using
     158                 : 
     159                 :     - one of @ref value's accessors, or
     160                 :     - a library-provided generic conversion, or
     161                 :     - a user-provided overload of `tag_invoke`.
     162                 : 
     163                 :     In order to perform the conversion the function selects an appropriate
     164                 :     implementation based on the types `T` and `Context` (if provided).
     165                 : 
     166                 :     1. If `Context` is available and is not `std::tuple<C...>`
     167                 : 
     168                 :        a. check if `use_category<T, Context>::value` is not
     169                 :           @ref conversion_category::unknown; otherwise
     170                 : 
     171                 :        b. check if a `tag_invoke` overload from the list below that takes a
     172                 :           `Context const&` exists.
     173                 : 
     174                 :     2. Otherwise, if `Context` is available, and is `std::tuple<C...>` repeat
     175                 :        steps **1** and **2** recursively for every `C` until either
     176                 :        step **1.a** or **1.b** succeeds for some `C`.
     177                 : 
     178                 :     3. Failing that,
     179                 : 
     180                 :        a. check if `use_category<T>::value` is not
     181                 :           @ref conversion_category::unknown; otherwise
     182                 : 
     183                 :        b. check if a `tag_invoke` overload from the list below that takes only
     184                 :           2 parameters exists; otherwise
     185                 : 
     186                 :        c. check if `T` is one of @ref value, @ref array, @ref object,
     187                 :           or @ref string; otherwise
     188                 : 
     189                 :        d. check if `T` matches one of the categories of types described in the
     190                 :           table "Conversion categories" in \<\<Value Conversion>> section.
     191                 : 
     192                 :     These steps determine both the appropriate category of conversion for `T`,
     193                 :     and, if necessary, the effective context `C` that will be used for
     194                 :     conversion. If the category is selected on steps **1.a**, **3.a**, **3.c**,
     195                 :     or **3.d**, the library provides a suitable conversion implementation.
     196                 :     If the category is selected on steps **2.b** or **3.b**, then a
     197                 :     user-provided `tag_invoke` overload is used.
     198                 : 
     199                 :     The overloads of `tag_invoke` that will be considered by this function
     200                 :     are in the following list. Overloads that appear higher in the list have
     201                 :     higher priority.
     202                 : 
     203                 :     @code
     204                 :     template< class FullContext >
     205                 :     result<T> tag_invoke( try_value_to_tag<T>, const value&, const Context&, const FullContext& );
     206                 : 
     207                 :     template< class FullContext >
     208                 :     T tag_invoke( value_to_tag<T>, const value&, const Context&, const FullContext& );
     209                 : 
     210                 :     result<T> tag_invoke( try_value_to_tag<T>, const value&, const Context& );
     211                 : 
     212                 :     T tag_invoke( value_to_tag<T>, const value&, const Context& );
     213                 : 
     214                 :     result<T> tag_invoke( try_value_to_tag<T>, const value& );
     215                 : 
     216                 :     T tag_invoke( value_to_tag<T>, const value& );
     217                 :     @endcode
     218                 : 
     219                 :     For `tag_invoke` overloads that take a parameter of type
     220                 :     `try_value_to_tag<T>` the object returned by a call to that overload is
     221                 :     returned by the function as the result of the conversion. For overloads
     222                 :     that take a parameter of type `value_to_tag<T>` the returned object is
     223                 :     wrapped with a `result<T>`.
     224                 : 
     225                 :     If an error occurs during conversion, the result will store the error code
     226                 :     associated with the error. If an exception is thrown, the function will
     227                 :     attempt to retrieve the associated error code and return it, otherwise it
     228                 :     will return @ref error::exception, unless the exception type is
     229                 :     @ref std::bad_alloc, which will be allowed to propagate.
     230                 : 
     231                 :     The `ctx` argument can be used either as a tag type to provide conversions
     232                 :     for third-party types, or to pass extra data to the conversion function.
     233                 : 
     234                 :     @par Constraints
     235                 :     @code
     236                 :     ! std::is_reference< T >::value
     237                 :     @endcode
     238                 : 
     239                 :     @par Exception Safety
     240                 :     Strong guarantee.
     241                 : 
     242                 :     @tparam T The type to convert to.
     243                 :     @tparam Context The type of context passed to the conversion function.
     244                 : 
     245                 :     @param jv The @ref value to convert.
     246                 :     @param ctx Context passed to the conversion function.
     247                 : 
     248                 :     @returns `jv` converted to `result<T>`.
     249                 : 
     250                 :     @see @ref value_to_tag, @ref value_to, @ref value_from,
     251                 :          [tag_invoke: A general pattern for supporting customisable functions](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf).
     252                 : 
     253                 :     @{
     254                 : */
     255                 : template< class T, class Context >
     256                 : typename result_for<T, value>::type
     257            3763 : try_value_to( value const& jv, Context const& ctx )
     258                 : {
     259                 :     BOOST_CORE_STATIC_ASSERT( ! std::is_reference<T>::value );
     260                 :     using bare_T = detail::remove_cvref<T>;
     261                 :     using cat = detail::value_to_category<Context, bare_T>;
     262            3573 :     return detail::value_to_impl(
     263            3757 :         cat(), try_value_to_tag<bare_T>(), jv, ctx );
     264                 : }
     265                 : 
     266                 : /// Overload
     267                 : template<class T>
     268                 : typename result_for<T, value>::type
     269             130 : try_value_to(const value& jv)
     270                 : {
     271             163 :     return try_value_to<T>( jv, detail::no_context() );
     272                 : }
     273                 : /// @}
     274                 : 
     275                 : /** Determine if a @ref value can be converted to `T`.
     276                 : 
     277                 :     If @ref value can be converted to `T` via a
     278                 :     call to @ref value_to, the static data member `value`
     279                 :     is defined as `true`. Otherwise, `value` is
     280                 :     defined as `false`.
     281                 : 
     282                 :     @see @ref value_to
     283                 : */
     284                 : #ifdef BOOST_JSON_DOCS
     285                 : template<class T>
     286                 : using has_value_to = __see_below__;
     287                 : #else
     288                 : template<class T>
     289                 : using has_value_to = detail::can_convert<
     290                 :     detail::remove_cvref<T>, detail::value_to_conversion>;
     291                 : #endif
     292                 : 
     293                 : } // namespace json
     294                 : } // namespace boost
     295                 : 
     296                 : #endif
        

Generated by: LCOV version 2.3