Repository: nlohmann/json
File: include/nlohmann/detail/conversions/to_json.hpp (C++)

Code before:
        j.assert_invariant();
    }
};

template<>
struct external_constructor<value_t::string>
{
    template<typename BasicJsonType>
    static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
    {
        j.m_type = value_t::string;
        j.m_value = s;
        j.assert_invariant();
    }

    template<typename BasicJsonType>
    static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
    {
        j.m_type = value_t::string;
        j.m_value = std::move(s);
        j.assert_invariant();
    }

	template<typename BasicJsonType, typename CompatibleStringType,
		     enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
		                 int> = 0>
		static void construct(BasicJsonType& j, const CompatibleStringType& str)
	{
		j.m_type = value_t::string;
		j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
		j.assert_invariant();
	}
};

template<>
struct external_constructor<value_t::number_float>
{
    template<typename BasicJsonType>
    static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
    {
        j.m_type = value_t::number_float;
        j.m_value = val;
        j.assert_invariant();
    }
};

template<>
struct external_constructor<value_t::number_unsigned>
{
    template<typename BasicJsonType>
    static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept

Review comment (suggestion):
This SFINAE check is already done in the `to_json` method, maybe we can only do it once:

- Adding a `to_json(const BasicJson::string_t&)` overload (only `BasicJson::string_t&&` is handled right now)
- Then, in the `to_json` overload where the `std::is_constructible<...>` check is performed, construct a `string_t` and move it to the `external_constructor`.

Additionally, I'd rather keep `external_constructor` function count low (Maybe the `array_t` specialization could get cleaned a bit).

This is mostly a style preference though.

Code after:
        j.assert_invariant();
    }
};

template<>
struct external_constructor<value_t::string>
{
    template<typename BasicJsonType>
    static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
    {
        j.m_type = value_t::string;
        j.m_value = s;
        j.assert_invariant();
    }

    template<typename BasicJsonType>
    static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
    {
        j.m_type = value_t::string;
        j.m_value = std::move(s);
        j.assert_invariant();
    }

	template<typename BasicJsonType, typename CompatibleStringType,
		 enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
		             int> = 0>
		static void construct(BasicJsonType& j, const CompatibleStringType& str)
	{
		j.m_type = value_t::string;
		j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
		j.assert_invariant();
	}
};

template<>
struct external_constructor<value_t::number_float>
{
    template<typename BasicJsonType>
    static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
    {
        j.m_type = value_t::number_float;
        j.m_value = val;
        j.assert_invariant();
    }
};

template<>
struct external_constructor<value_t::number_unsigned>
{
    template<typename BasicJsonType>
    static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept