LCOV - code coverage report
Current view: top level - json - value_from.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 92.3 % 13 12 1
Test Date: 2026-07-10 12:38:05 Functions: 98.5 % 535 527 8

           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_FROM_HPP
      13                 : #define BOOST_JSON_VALUE_FROM_HPP
      14                 : 
      15                 : #include <boost/core/detail/static_assert.hpp>
      16                 : #include <boost/json/detail/value_from.hpp>
      17                 : 
      18                 : namespace boost {
      19                 : namespace json {
      20                 : 
      21                 : /** Convert an object of type `T` to @ref value.
      22                 : 
      23                 :     This function attempts to convert an object of type `T` to @ref value using
      24                 : 
      25                 :     - one of @ref value's constructors,
      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                 :     void tag_invoke( value_from_tag, value&, T, const Context&, const FullContext& );
      72                 : 
      73                 :     void tag_invoke( value_from_tag, value&, T, const Context& );
      74                 : 
      75                 :     void tag_invoke( value_from_tag, value&, T );
      76                 :     @endcode
      77                 : 
      78                 :     The `ctx` argument can be used either as a tag type to provide conversions
      79                 :     for third-party types, or to pass extra data to the conversion function.
      80                 : 
      81                 :     Overloads **(2)** and **(4)** construct their return value using the
      82                 :     @ref storage_ptr `sp`, which ensures that the memory resource is correctly
      83                 :     propagated.
      84                 : 
      85                 :     @par Exception Safety
      86                 :     Strong guarantee.
      87                 : 
      88                 :     @tparam T The type of the object to convert.
      89                 : 
      90                 :     @tparam Context The type of context passed to the conversion function.
      91                 : 
      92                 :     @param t The object to convert.
      93                 : 
      94                 :     @param ctx Context passed to the conversion function.
      95                 : 
      96                 :     @param jv @ref value out parameter.
      97                 : 
      98                 :     @see @ref value_from_tag, @ref value_to,
      99                 :     <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
     100                 :         tag_invoke: A general pattern for supporting customisable functions</a>
     101                 : */
     102                 : /// @{
     103                 : template< class T, class Context >
     104                 : void
     105 HIT        7056 : value_from(
     106                 :     T&& t,
     107                 :     Context const& ctx,
     108                 :     value& jv)
     109                 : {
     110                 :     using bare_T = detail::remove_cvref<T>;
     111                 :     using cat = detail::value_from_category<Context, bare_T>;
     112            7056 :     detail::value_from_impl( cat(), jv, std::forward<T>(t), ctx );
     113            7056 : }
     114                 : 
     115                 : /** Overload
     116                 :    @param t
     117                 :    @param ctx
     118                 :    @param sp A storage pointer referring to the memory resource to use for the
     119                 :    returned @ref value.
     120                 : 
     121                 :    @return Overloads **(2)** and **(4)** return `t` converted to @ref value.
     122                 :    Overloads **(1)** and **3** return `void` instead and pass their result via
     123                 :    the out parameter `jv`.
     124                 : */
     125                 : template< class T, class Context >
     126                 : #ifndef BOOST_JSON_DOCS
     127                 : typename std::enable_if<
     128                 :     !std::is_same< detail::remove_cvref<Context>, storage_ptr >::value &&
     129                 :     !std::is_same< detail::remove_cvref<Context>, value >::value,
     130                 :     value >::type
     131                 : #else
     132                 : value
     133                 : #endif
     134            7037 : value_from(
     135                 :     T&& t,
     136                 :     Context const& ctx,
     137                 :     storage_ptr sp = {})
     138                 : {
     139            7037 :     value jv(std::move(sp));
     140            7037 :     value_from( static_cast<T&&>(t), ctx, jv );
     141            7037 :     return jv;
     142 MIS           0 : }
     143                 : 
     144                 : /// Overload
     145                 : template<class T>
     146                 : void
     147 HIT          19 : value_from(
     148                 :     T&& t,
     149                 :     value& jv)
     150                 : {
     151              19 :    value_from( static_cast<T&&>(t), detail::no_context(), jv );
     152              19 : }
     153                 : 
     154                 : /// Overload
     155                 : template<class T>
     156                 : value
     157             297 : value_from(
     158                 :     T&& t,
     159                 :     storage_ptr sp = {})
     160                 : {
     161                 :    return value_from(
     162             297 :            static_cast<T&&>(t), detail::no_context(), std::move(sp) );
     163                 : }
     164                 : /// @}
     165                 : 
     166                 : /** Determine if `T` can be converted to @ref value.
     167                 : 
     168                 :     If `T` can be converted to @ref value via a call to @ref value_from, the
     169                 :     static data member `value` is defined as `true`. Otherwise, `value` is
     170                 :     defined as `false`.
     171                 : 
     172                 :     @see @ref value_from.
     173                 : */
     174                 : #ifdef BOOST_JSON_DOCS
     175                 : template<class T>
     176                 : using has_value_from = __see_below__;
     177                 : #else
     178                 : template<class T>
     179                 : using has_value_from = detail::can_convert<
     180                 :     detail::remove_cvref<T>, detail::value_from_conversion>;
     181                 : #endif
     182                 : 
     183                 : } // namespace json
     184                 : } // namespace boost
     185                 : 
     186                 : #endif
        

Generated by: LCOV version 2.3