#include #include #include #include #include #include #include namespace hex_cast { namespace traits { template struct is_container : boost::spirit::traits::is_container {}; template struct is_integral : boost::is_integral {}; } //hex template typename boost::enable_if, void>::type hex(I const& in, O out) { if(!boost::spirit::karma::generate(out, boost::spirit::karma::hex, in)) throw std::bad_cast(); } template void hex(I first, I last, O out) { for(; first != last; ++first) hex(*first, out); } template typename boost::enable_if, void>::type hex(I const& in, O out) { return hex(in.begin(), in.end(), out); } template typename boost::enable_if, O>::type hex_as(I const& input) { O temp; temp.reserve(sizeof(I) * 2); hex(input, std::back_inserter(temp)); return temp; } template typename boost::enable_if, O>::type hex_as(I const& input) { O temp; temp.reserve(input.size() * sizeof(typename I::value_type) * 2); hex(input, std::back_inserter(temp)); return temp; } //unhex template typename boost::enable_if, void>::type unhex(I& first, I& last, O& out) { boost::spirit::qi::uint_parser hex_parser; if(!boost::spirit::qi::parse(first, last, hex_parser, out)) throw std::bad_cast(); } template typename boost::enable_if, void>::type unhex(I const& first, I const& last, O& out) { I f(first), l(last); unhex(f, l, out); //might be a good idea sometime // return first == last; //did we get a full match? } template typename boost::disable_if, void>::type unhex(I ifirst, I ilast, O ofirst) { for(; ifirst != ilast; ++ofirst) unhex(ifirst, ilast, *ofirst); } template void unhex(I ifirst, I ilast, O ofirst, O olast) { for(; ofirst != olast && ifirst != ilast; ++ofirst) unhex(ifirst, ilast, *ofirst); } template typename boost::enable_if, void>::type unhex(I const& in, O ofirst, O olast) { return unhex(in.first(), in.last(), ofirst, olast); } template typename boost::enable_if, traits::is_integral >, void>::type unhex(I const& in, O& out) { return unhex(in.begin(), in.end(), out); } template typename boost::enable_if, traits::is_container >, void>::type unhex(I const& in, O& out) { // return unhex(in.begin(), in.end(), std::back_inserter(out)); //Doesn't work... typename I::const_iterator ifirst(in.begin()), ilast(in.end()); typename O::value_type temp; for(; ifirst != ilast;) { unhex(ifirst, ilast, temp); out.push_back(temp); } } template typename boost::enable_if, O>::type unhex_as(I const& input) { O temp; unhex(input, temp); return temp; } template typename boost::enable_if, O>::type unhex_as(I const& input) { O temp; temp.reserve(input.size() * sizeof(typename I::value_type) / 2); unhex(input, temp); return temp; } } int main() { { std::string s("abode"); std::string o; hex_cast::hex(s, std::back_inserter(o)); std::cout << "0x" << o << std::endl; std::cout << "0x" << hex_cast::hex_as(0x123456) << std::endl; std::wcout << "0x" << hex_cast::hex_as(0x123456) << std::endl; std::cout << "0x" << hex_cast::hex_as(s) << std::endl; // std::cout << "0x" << hex_cast::hex_as("abode") << std::endl; } std::cout << std::endl; { std::string s("61626f6465"); std::string os; unsigned long ol; std::vector ov; hex_cast::unhex(s.begin(), s.end(), ol); std::cout << std::hex << ol << std::endl; hex_cast::unhex(s, os); std::cout << os << std::endl; std::cout << hex_cast::unhex_as(s) << std::endl; std::cout << hex_cast::unhex_as(s) << std::endl; std::cout << std::endl; hex_cast::unhex(s, ov); std::copy(ov.begin(), ov.end(), std::ostream_iterator(std::cout, " ")); std::cout << std::endl; } return 0; }