文字列から型への変換

mpllibs のコードを見ていて、ふと思いついたのでやってみました。

[ソース]

#include <boost/preprocessor/enum.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/string.hpp>


template<std::size_t Index, typename Char, typename std::size_t N>
constexpr Char
at_c(Char (&str)[N]){
    return Index >= N
         ? Char('\0')
         : str[Index];
}

#define STRING_MAX_LENGTH    BOOST_MPL_LIMIT_VECTOR_SIZE

#define DECL_AT_C(z, n, text)    \
    at_c<n>(text)

#define _(str)    \
    boost::mpl::vector_c<char, BOOST_PP_ENUM(STRING_MAX_LENGTH, DECL_AT_C, str)>


#include <iostream>
#include <boost/mpl/print.hpp>
#include <boost/mpl/equal.hpp>

template<typename String>
void
print(){
    namespace m =boost::mpl;
    std::cout << m::c_str<String>::value << std::endl;
}

int
main(){
    typedef _("homuhomu") str;
    print<str>();
    print<_("madomado")>();
    print<_("mamimami")>();

    return 0;
}

[出力]

homuhomu
madomado
mamimami


どうやって実装しているのかというと、ソースを見てもらえれば分かると思うんですが、

m::vector_c<char, "homu"[0], "homu"[1], "homu"[2], "homu"[3], "homu"[4], ...>


と、いうように文字列の各文字を STRING_MAX_LENGTH の数だけ展開しています。
(実際にはサイズ外ならば '\0' にしていますが。
サイズに制限はありますが、これなら割りとスマートに文字列から型の変換が出来るんじゃないでしょうか。
Sprout.String のような constexpr string でも実装できると思います。
あと実際に mpllibs がこうやっているのかはわかりません。

[コンパイラ]

  • g++ (GCC) 4.7.0 20120218 (experimental)
  • clang++ (LLVM) 3.1 20120327(trunk)