qi::int_parser,qi::uint_parser の使いかた
Spirit.Qi には、qi::int_ や qi::uint_ といった、に数値文字列にマッチするプリミティブパーサが用意されている。
これらの Attribute は int や unsigned である。
もし short や unsigned short の Attribute を用いたければ、qi::short_ や qi::ushort_ を使えばよいし、
8進数や16進数をパースしたければ、qi::oct や qi::hex を使えばよい。
さて、では unsigned char 等の Attribute を用いて数値文字列をパースしたいときはどうすればよいだろうか。
残念ながら、qi::schar_ や qi::uchar_ といったプリミティブパーサは用意されていない。
そういった、標準で用意されていないバリエーションの、数値文字列にマッチするパーサを使うには、
qi::int_parser や qi::uint_parser を使えばよい。
なお、これらは Spirit.Qi のドキュメントには記載されていない。
(サンプルコード等にはあるかもしれないが)
※載ってました。
http://www.boost.org/doc/libs/1_46_0/libs/spirit/doc/html/spirit/qi/reference/numeric/int.html
http://www.boost.org/doc/libs/1_46_0/libs/spirit/doc/html/spirit/qi/reference/numeric/uint.html
これが定義されているヘッダは、
である。
// This one is the class that the user can instantiate directly in // order to create a customized int parser template <typename T = int, unsigned Radix = 10, unsigned MinDigits = 1 , int MaxDigits = -1> struct int_parser;
// This one is the class that the user can instantiate directly in // order to create a customized int parser template <typename T = int, unsigned Radix = 10, unsigned MinDigits = 1 , int MaxDigits = -1> struct uint_parser;
コメントにあるように、これらは「ユーザーがカスタマイズされた整数型のパーサを作成するために直接インスタンス化できるクラス」である。
-
- T は Attribute の整数型である。
- Radix は基数である。
- MinDigits は最小の桁数で、MaxDigits は最大の桁数である。
試しにコードを書いてみる。
以下は、カンマ区切りの8bit数値をパースして IPv4 アドレスに格納する。
#include <iostream> #include <string> #include <boost/asio/ip/address_v4.hpp> #include <boost/spirit/include/qi.hpp> #include <boost/fusion/include/vector_tie.hpp> namespace qi = boost::spirit::qi; int main() { typedef boost::asio::ip::address_v4::bytes_type bytes_type; // boost::array<unsigned char, 4> typedef bytes_type::value_type byte_type; // unsigned char typedef qi::uint_parser<byte_type> uchar_p; std::string input("127,0,0,1"); bytes_type bytes; qi::parse( input.begin(), input.end(), uchar_p() >> ',' >> uchar_p() >> ',' >> uchar_p() >> ',' >> uchar_p(), boost::fusion::vector_tie(bytes[0], bytes[1], bytes[2], bytes[3]) ); boost::asio::ip::address_v4 ipv4(bytes); std::cout << "IPv4 = " << ipv4 << std::endl; }
なお fusion::vector_tie() は、参照のタプルを作成する。
boost::array は、アダプトすることで Fusion のシーケンスとして扱うこともできるのだが、
この場合はそうしてもコンテナとして解釈され、コンパイルエラーになってしまう。
そのため各要素の参照を fusion::vector に纏めている。
出力は以下のようになる。
(VC9 + Boost 1.46.1)
IPv4 = 127.0.0.1