<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="">= Custom Conversions Boost.JSON uses two mechanisms to customize conversion between &lt;&lt;ref_value&gt;&gt; and user types. One mechanism involves specializing type traits. The other one is more powerful and requires defining overloads of `tag_invoke`. Both mechanisms will be further explained in this section.</string>
    <string name="">Conversion Traits</string>
    <string name="">"Previously a number of conversion type traits, like &lt;&lt;ref_is_tuple_like&gt;&gt; or &lt;&lt;ref_is_sequence_like&gt;&gt;,  were introduced. The library tries the traits one after another and uses the implementation that corresponds to the first matching trait. In some cases, though, a type would match a trait with a higher priority, but the user intends for it to belong to a lower priority category. If this happens the user can specialize the trait that\'s not supposed to match for that type to be an equivalent of `std::false_type`."</string>
    <string name="">Consider this type:</string>
    <string name="">It exposes both a sequence API and a tuple API. But converting from &lt;&lt;ref_value&gt;&gt; to `user_ns::ip_address` would not be able to use implementation for sequences, since those are constructed empty and then populated one element at a time, while `ip_address` has a fixed size of 4. The tuple conversion would fit, though. The only problem is that &lt;&lt;ref_is_tuple_like&gt;&gt; has a lower priority than &lt;&lt;ref_is_sequence_like&gt;&gt;. In order to circumvent this, the user only needs to specialize &lt;&lt;ref_is_sequence_like&gt;&gt; to not match `ip_address`.</string>
    <string name="">`tag_invoke` Overloads</string>
    <string name="">The second, more powerful approach, is to provide the conversion implementation yourself. With Boost.JSON this is done by defining an overload of `tag_invoke` function (the benefits of this mechanism are outlined in http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf[C++ proposal P1895]. In essence, `tag_invoke` provides a uniform interface for defining customization points by using argument-dependent lookup to find a viable overload from the point at which it is called. As the name suggests, a tag type is passed as an argument in order to:</string>
    <string name="">discard candidates that are unrelated to that particular</string>
    <string name="">customization point, and</string>
    <string name="">embed the user-defined type into the arguments list (e.g. by using a tag type</string>
    <string name="">template such as `value_to_tag&lt;T&gt;`) so that its http://eel.is/c++draft/basic.lookup.argdep#2[associated namespaces and entities] are examined when name lookup is performed.</string>
    <string name="">This has the effect of finding user-provided `tag_invoke` overloads, even if they are declared (lexically) after the definition of the calling function.</string>
    <string name="">Overloads of `tag_invoke` called by &lt;&lt;ref_value_from&gt;&gt; take the form:</string>
    <string name="">``` void tag_invoke( const value_from_tag&amp;, value&amp;, T ); ```</string>
    <string name="">While overloads of `tag_invoke` called by &lt;&lt;ref_value_to&gt;&gt; take the form:</string>
    <string name="">``` T tag_invoke( const value_to_tag&lt; T &gt;&amp;, const value&amp; ); ```</string>
    <string name="">If we implemented conversion for `user_ns::ip_address` manually with this approach, it would look like this:</string>
    <string name="">Since the type being converted is embedded into the function\'s signature, user-provided overloads are visible to argument-dependent lookup and will be candidates when a conversion is performed:</string>
    <string name="">Users can freely combine types with custom conversions with types with library-provided conversions. The library handles them correctly:</string>
</resources>
