ユーザ定義リテラルからpairを作る

ユーザ定義リテラルはその制約のキツさから全然融通が効かないので、あんまり遊べる要素とか面白い利用法とかが見つからないのですが、少し変わった利用が出来ないか考えてみました。

#include <type_traits>

namespace ct {
    static constexpr std::size_t period = static_cast<std::size_t>('.');
    static constexpr std::size_t zero = static_cast<std::size_t>('0');
    
    template <std::size_t f, std::size_t l>
    struct pair
    {
        static constexpr auto first = f;
        static constexpr auto last = l;
    };
    
    template <bool lr, bool finish, std::size_t f, std::size_t l, char c, char... chars>
    struct pair_literal
    {
        using type = pair<f, 10 * l + (c - zero)>;
    };
    
    template <std::size_t f, std::size_t l, char c, char... chars>
    struct pair_literal<false, false, f, l, c, chars...> :
    pair_literal <c == period, false, c == period ? f : f * 10 + (c - zero), l, chars...>
    {};

    template <std::size_t f, std::size_t l, char c, char... chars>
    struct pair_literal<true, false, f, l, c, chars...> :
    pair_literal <true, sizeof...(chars) == 1, f, l * 10 + (c - zero), chars...>
    {};

    template <char... chars>
    static constexpr typename pair_literal<false, false, 0, 0, chars...>::type operator "" _p()
    {
        return typename pair_literal<false, false, 0, 0, chars...>::type();
    }
}

int main()
{
    using namespace ct;
    static constexpr auto tmp = 2.1024_p;
    static_assert(tmp.first == 2 && tmp.last == 1024, "");
}

ピリオドを区切り文字としてx.y_pでxとyのpairを生成しています。
残念ながら制約上出来るのは2項だけ、型も固定です。

実用性ありませんね。

もう少し制約がゆるいと色々出来そうなのですが。