
Hi, Does Boost have hex/unhex() that support std::string? I can't find them and I think they'd be quite handy to have. -- Olaf

On Nov 1, 2011, at 1:09 PM, Olaf van der Spek wrote:
Does Boost have hex/unhex() that support std::string? I can't find them and I think they'd be quite handy to have.
I don't know of any. (I'm assuming that you're talking about the calls from MySQL - http://www.java2s.com/Tutorial/MySQL/0460__String-Functions/0920__UNHEX.htm) I suspect, but haven't tried, that they would be one or two-liners in Boost.Spirit. You want something like this? template <typename InputIterator, typename OutputIterator> OutputIterator hex ( InputIterator first, InputIterator last, OutputIterator out ); template <typename InputIterator, typename OutputIterator> OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator out ); [ + range based versions ] [ + versions that work on char/wchar_t/short/int/long/long long, etc] -- Marshall Marshall Clow Idio Software <mailto:mclow.lists@gmail.com> A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait). -- Yu Suzuki

On Tue, Nov 1, 2011 at 9:29 PM, Marshall Clow <mclow.lists@gmail.com> wrote:
You want something like this? template <typename InputIterator, typename OutputIterator> OutputIterator hex ( InputIterator first, InputIterator last, OutputIterator out );
template <typename InputIterator, typename OutputIterator> OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator out );
[ + range based versions ] [ + versions that work on char/wchar_t/short/int/long/long long, etc]
No, I'm looking for one that returns std::string. Although the generic versions might be useful too. How would your unhex() flag an error? -- Olaf

On Nov 1, 2011, at 3:26 PM, Olaf van der Spek wrote:
On Tue, Nov 1, 2011 at 9:29 PM, Marshall Clow <mclow.lists@gmail.com> wrote:
You want something like this? template <typename InputIterator, typename OutputIterator> OutputIterator hex ( InputIterator first, InputIterator last, OutputIterator out );
template <typename InputIterator, typename OutputIterator> OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator out );
[ + range based versions ] [ + versions that work on char/wchar_t/short/int/long/long long, etc]
No, I'm looking for one that returns std::string. Although the generic versions might be useful too.
std::string input ( "61626f6465" ); std::string result; unhex ( input.begin(), input.end (), std::back_inserter(result)); ---> result should contain "abode"
How would your unhex() flag an error?
Throw an exception. -- Marshall Marshall Clow Idio Software <mailto:mclow.lists@gmail.com> A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait). -- Yu Suzuki

On Tue, Nov 1, 2011 at 11:32 PM, Marshall Clow <mclow.lists@gmail.com> wrote:
std::string input ( "61626f6465" ); std::string result; unhex ( input.begin(), input.end (), std::back_inserter(result));
---> result should contain "abode"
That one does not return std::string. It's also sub-optimal.
How would your unhex() flag an error?
Throw an exception.
Hmm. I'd like to see a non-throwing variant as well. -- Olaf

On 2 November 2011 00:05, Olaf van der Spek <ml@vdspek.org> wrote:
On Tue, Nov 1, 2011 at 11:32 PM, Marshall Clow <mclow.lists@gmail.com> wrote:
std::string input ( "61626f6465" ); std::string result; unhex ( input.begin(), input.end (), std::back_inserter(result));
---> result should contain "abode"
I seem to have misinterpreted your initial request (I thought you were taking about parsing / generating hexadecimal numbers), what's described above isn't supported my boost.coerce, sorry.
That one does not return std::string. It's also sub-optimal.
How would your unhex() flag an error?
Throw an exception.
Hmm. I'd like to see a non-throwing variant as well.
-- Olaf
Jeroen

On 1 November 2011 21:09, Olaf van der Spek <ml@vdspek.org> wrote:
Hi,
Does Boost have hex/unhex() that support std::string? I can't find them and I think they'd be quite handy to have.
-- Olaf
The library that I'm working on, boost.coerce, is capable of this. It's a extensible type-to-string and string-to-type conversion library and tag::hex is one of the current extensions. Please refer to http://svn.boost.org/svn/boost/sandbox/coerce/libs/coerce/example/tag.cpp for an example, and http://svn.boost.org/svn/boost/sandbox/coerce/ for the source code. It should be production stable, only the documentation is still in need of some love before it can be reviewed. If you have any questions, please don't hesitate to contact me. Kind regards, Jeroen

02.11.2011 0:09, Olaf van der Spek пишет:
Does Boost have hex/unhex() that support std::string? I can't find them and I think they'd be quite handy to have. How exactly should it interpret the following lines: 01 02 0102 01 02 010 2 012 01 2 01\n02 01 | 02 etc.
For the boost library, we need the universal parser that can be customized by the policies. It is also reasonable to have the range-based, stream-based, 0-terminated and wchar_t-based versions. But it is much easier to write exactly what you need in your code. -- Best regards, Sergey Cheban

On Wed, Nov 2, 2011 at 7:52 AM, Sergey Cheban <s.cheban@drweb.com> wrote:
02.11.2011 0:09, Olaf van der Spek пишет:
Does Boost have hex/unhex() that support std::string? I can't find them and I think they'd be quite handy to have.
How exactly should it interpret the following lines: 01 02 0102 01 02 010 2 012 01 2 01\n02 01 | 02 etc.
Good question. I'd be happy with one that only accepts the simplest variant.
For the boost library, we need the universal parser that can be customized by the policies. It is also reasonable to have the range-based, stream-based, 0-terminated and wchar_t-based versions.
But it is much easier to write exactly what you need in your code.
Not really. Copy/paste development is bad. ;) -- Olaf

On Wed, Nov 2, 2011 at 7:52 AM, Sergey Cheban <s.cheban@drweb.com> wrote:
02.11.2011 0:09, Olaf van der Spek пишет:
Does Boost have hex/unhex() that support std::string? I can't find them and I think they'd be quite handy to have.
How exactly should it interpret the following lines: 01 02 0102 01 02 010 2 012 01 2 01\n02 01 | 02 etc.
Good question. I'd be happy with one that only accepts the simplest variant.
For the boost library, we need the universal parser that can be customized by the policies. It is also reasonable to have the range-based, stream-based, 0-terminated and wchar_t-based versions.
But it is much easier to write exactly what you need in your code.
Not really. Copy/paste development is bad. ;)
As Marshal pointed out, Spirit supports that easily: std::string input("61626f6465"); std::string str; if (qi::parse(input.begin(), input.end(), qi::hex, str)) assert(str == "abode"); and std::string str("abode"); std::string output; if (karma::generate(back_inserter(output), karma::hex, str)) assert(output == "61626f6465"); If you want to avoid the cost of possible reallocations in output, just call output.reserve(...) upfront. Otherwise both code snippets generate code equivalent to hand written assembly and have been shown to be as fast as it can get. HTH Regards Hartmut --------------- http://boost-spirit.com http://stellar.cct.lsu.edu

On Wed, Nov 2, 2011 at 12:32 PM, Hartmut Kaiser <hartmut.kaiser@gmail.com> wrote:
As Marshal pointed out, Spirit supports that easily:
std::string input("61626f6465"); std::string str; if (qi::parse(input.begin(), input.end(), qi::hex, str)) assert(str == "abode");
Is there no range-based variant of parse()?
and
std::string str("abode"); std::string output; if (karma::generate(back_inserter(output), karma::hex, str)) assert(output == "61626f6465");
If you want to avoid the cost of possible reallocations in output, just call output.reserve(...) upfront. Otherwise both code snippets generate code equivalent to hand written assembly and have been shown to be as fast as it can get.
When would generate() fail (return false)? AFAIK to hex can't fail and in that case a variant that returns std::string would be nicer. -- Olaf

On Wed, Nov 2, 2011 at 12:32 PM, Hartmut Kaiser <hartmut.kaiser@gmail.com> wrote:
As Marshal pointed out, Spirit supports that easily:
std::string input("61626f6465"); std::string str; if (qi::parse(input.begin(), input.end(), qi::hex, str)) assert(str == "abode");
Is there no range-based variant of parse()?
and
std::string str("abode"); std::string output; if (karma::generate(back_inserter(output), karma::hex, str)) assert(output == "61626f6465");
If you want to avoid the cost of possible reallocations in output, just call output.reserve(...) upfront. Otherwise both code snippets generate code equivalent to hand written assembly and have been shown to be as fast as it can get.
When would generate() fail (return false)? AFAIK to hex can't fail and in that case a variant that returns std::string would be nicer.
Actually, please disregard what I wrote, it is complete nonsense. I misread your initial mail. Note to self: drink coffee before responding to email! Regards Hartmut --------------- http://boost-spirit.com http://stellar.cct.lsu.edu

On Wed, Nov 2, 2011 at 12:54 PM, Hartmut Kaiser <hartmut.kaiser@gmail.com> wrote:
On Wed, Nov 2, 2011 at 12:32 PM, Hartmut Kaiser <hartmut.kaiser@gmail.com> wrote:
As Marshal pointed out, Spirit supports that easily:
std::string input("61626f6465"); std::string str; if (qi::parse(input.begin(), input.end(), qi::hex, str)) assert(str == "abode");
Is there no range-based variant of parse()?
and
std::string str("abode"); std::string output; if (karma::generate(back_inserter(output), karma::hex, str)) assert(output == "61626f6465");
If you want to avoid the cost of possible reallocations in output, just call output.reserve(...) upfront. Otherwise both code snippets generate code equivalent to hand written assembly and have been shown to be as fast as it can get.
When would generate() fail (return false)? AFAIK to hex can't fail and in that case a variant that returns std::string would be nicer.
Actually, please disregard what I wrote, it is complete nonsense. I misread your initial mail.
Note to self: drink coffee before responding to email!
Why? Your functions seem quite close to the desired functionality. -- Olaf

As Marshal pointed out, Spirit supports that easily:
std::string input("61626f6465"); std::string str; if (qi::parse(input.begin(), input.end(), qi::hex, str)) assert(str == "abode");
Is there no range-based variant of parse()?
and
std::string str("abode"); std::string output; if (karma::generate(back_inserter(output), karma::hex, str)) assert(output == "61626f6465");
If you want to avoid the cost of possible reallocations in output, just call output.reserve(...) upfront. Otherwise both code snippets generate code equivalent to hand written assembly and have been shown to be as fast as it can get.
When would generate() fail (return false)? AFAIK to hex can't fail and in that case a variant that returns std::string would be nicer.
Actually, please disregard what I wrote, it is complete nonsense. I misread your initial mail.
Note to self: drink coffee before responding to email!
Why? Your functions seem quite close to the desired functionality.
Here is what Spirit can do: std::string input("61626f6465"); unsigned ui; if (qi::parse(input.begin(), input.end(), qi::hex, ui)) assert(ui == 0x61626f6465); and unsigned ui = 0x61626f6465; std::string output; if (karma::generate(back_inserter(output), karma::hex, ui)) assert(output == "61626f6465"); As I said, I wrote nonsense with regard to your question. Sorry for the confusion. Regards Hartmut --------------- http://boost-spirit.com http://stellar.cct.lsu.edu

On Wed, Nov 2, 2011 at 1:12 PM, Hartmut Kaiser <hartmut.kaiser@gmail.com> wrote:
As I said, I wrote nonsense with regard to your question. Sorry for the confusion.
When would generate() fail (return false)? AFAIK to hex can't fail and in that case a variant that returns std::string would be nicer. -- Olaf

On Wed, Nov 2, 2011 at 1:12 PM, Hartmut Kaiser <hartmut.kaiser@gmail.com> wrote:
As I said, I wrote nonsense with regard to your question. Sorry for the confusion.
When would generate() fail (return false)?
Generate fails either if one of the used generators fail or if the underlying output iterator reports an error.
AFAIK to hex can't fail and in that case a variant that returns std::string would be nicer.
Doesn't it 'return' a std::string? If you dislike the current API a small wrapper function can easily handle that. But just to avoid confusion: what API are you looking for? std::string("61626f6465") --> std::string("abode") or rather: 0x61626f6465UL --> string("abode") (none of which can be easily done with Spirit, btw). Regards Hartmut --------------- http://boost-spirit.com http://stellar.cct.lsu.edu

On Wed, Nov 2, 2011 at 8:05 PM, Hartmut Kaiser <hartmut.kaiser@gmail.com> wrote:
On Wed, Nov 2, 2011 at 1:12 PM, Hartmut Kaiser <hartmut.kaiser@gmail.com> wrote:
As I said, I wrote nonsense with regard to your question. Sorry for the confusion.
When would generate() fail (return false)?
Generate fails either if one of the used generators fail or if the underlying output iterator reports an error.
AFAIK to hex can't fail and in that case a variant that returns std::string would be nicer.
Doesn't it 'return' a std::string? If you dislike the current API a small
No, the return value is an output iterator. This forces me to use a temp var.
wrapper function can easily handle that.
True
But just to avoid confusion: what API are you looking for?
std::string("61626f6465") --> std::string("abode")
This one
or rather:
0x61626f6465UL --> string("abode")
(none of which can be easily done with Spirit, btw).
-- Olaf

On Nov 2, 2011, at 12:05 PM, Hartmut Kaiser wrote:
On Wed, Nov 2, 2011 at 1:12 PM, Hartmut Kaiser <hartmut.kaiser@gmail.com> wrote:
As I said, I wrote nonsense with regard to your question. Sorry for the confusion.
When would generate() fail (return false)?
Generate fails either if one of the used generators fail or if the underlying output iterator reports an error.
AFAIK to hex can't fail and in that case a variant that returns std::string would be nicer.
Sure it can. The container that you are putting it into (std::string, say) could fail on memory allocation. Just because it's really unlikely doesn't mean it can't happen. (If you don't want to worry about it, then don't)
Doesn't it 'return' a std::string? If you dislike the current API a small wrapper function can easily handle that.
Right - like this (for example): std::string hexS ( const std::string &input ) { std::string result; result.reserve ( input.size () * 2 ); // Harry Harrison hex ( input, std::back_inserter ( result )); return result; } ( I apologize for my idiosyncratic commenting style; I tend to figure everyone knows that Harry Harrison wrote a science fiction novel titled "Make Room! Make Room!" ) http://en.wikipedia.org/wiki/Make_Room!_Make_Room!
But just to avoid confusion: what API are you looking for?
std::string("61626f6465") --> std::string("abode")
or rather:
0x61626f6465UL --> string("abode")
(none of which can be easily done with Spirit, btw).
I think that he means the former. -- Marshall Marshall Clow Idio Software <mailto:mclow.lists@gmail.com> A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait). -- Yu Suzuki

On Wed, Nov 2, 2011 at 8:32 PM, Marshall Clow <mclow.lists@gmail.com> wrote:
AFAIK to hex can't fail and in that case a variant that returns std::string would be nicer.
Sure it can. The container that you are putting it into (std::string, say) could fail on memory allocation. Just because it's really unlikely doesn't mean it can't happen. (If you don't want to worry about it, then don't)
Right, but wouldn't the exception just be propagated to the caller?
Doesn't it 'return' a std::string? If you dislike the current API a small wrapper function can easily handle that.
Right - like this (for example):
std::string hexS ( const std::string &input ) { std::string result; result.reserve ( input.size () * 2 ); // Harry Harrison hex ( input, std::back_inserter ( result )); return result; }
Yep, except that it should not be limited to std::string. Olaf

On Nov 2, 2011, at 1:32 PM, Olaf van der Spek wrote:
On Wed, Nov 2, 2011 at 8:32 PM, Marshall Clow <mclow.lists@gmail.com> wrote:
AFAIK to hex can't fail and in that case a variant that returns std::string would be nicer.
Sure it can. The container that you are putting it into (std::string, say) could fail on memory allocation. Just because it's really unlikely doesn't mean it can't happen. (If you don't want to worry about it, then don't)
Right, but wouldn't the exception just be propagated to the caller?
Sure - but if you believe that it could happen, then you should handle it. If you think it won't ever happen, then don't.
Doesn't it 'return' a std::string? If you dislike the current API a small wrapper function can easily handle that.
Right - like this (for example):
std::string hexS ( const std::string &input ) { std::string result; result.reserve ( input.size () * 2 ); // Harry Harrison hex ( input, std::back_inserter ( result )); return result; }
Yep, except that it should not be limited to std::string.
Goodness, you're picky. First you say it needs to "just work on std::string", then you say it shouldn't be limited to std::string. The iterator-based versions (whose prototypes I posted earlier) work on just about everything. -- Marshall Marshall Clow Idio Software <mailto:mclow.lists@gmail.com> A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait). -- Yu Suzuki

On Wed, Nov 2, 2011 at 9:43 PM, Marshall Clow <mclow.lists@gmail.com> wrote:
Doesn't it 'return' a std::string? If you dislike the current API a small wrapper function can easily handle that.
Right - like this (for example):
std::string hexS ( const std::string &input ) { std::string result; result.reserve ( input.size () * 2 ); // Harry Harrison hex ( input, std::back_inserter ( result )); return result; }
Yep, except that it should not be limited to std::string.
Goodness, you're picky.
Hehe
First you say it needs to "just work on std::string", then you say it shouldn't be limited to std::string.
The iterator-based versions (whose prototypes I posted earlier) work on just about everything.
So could a function like this be added to Boost? Olaf

Hi,
As Marshal pointed out, Spirit supports that easily
Actually, please disregard what I wrote, it is complete nonsense. I misread your initial mail.
Note to self: drink coffee before responding to email!
Regards Hartmut
Actually, it's not really difficult. hex() is done, unhex() is up to someone else, cause I've got to go: #include <iostream> #include <string> #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/karma.hpp> namespace hex_cast { template<class T> std::string hex(T const& input) { typedef typename T::const_iterator iterator_t; std::string temp; temp.reserve(input.size() * sizeof(typename T::value_type) * 2); iterator_t it(input.begin()), end(input.end()); using boost::spirit::karma::generate; using boost::spirit::karma::hex; for(; it != end; ++it) generate(std::back_inserter(temp), hex, *it); return temp; } } int main() { std::string s("abode"); std::cout << hex_cast::hex(s) << std::endl; return 0; } HTH michi7x7

On Nov 2, 2011, at 1:32 PM, michi7x7 wrote:
Hi,
As Marshal pointed out, Spirit supports that easily
There are two 'll's at the end of my name, actually ;-)
Actually, please disregard what I wrote, it is complete nonsense. I misread your initial mail.
Note to self: drink coffee before responding to email!
Regards Hartmut
Actually, it's not really difficult.
Nice! I made it more general: template<class InputIterator, typename OutputIterator> OutputIterator hex ( InputIterator first, InputIterator last, OutputIterator out ) { for ( ; first != last; ++first ) boost::spirit::karma::generate (out, boost::spirit::karma::hex, *first); return out; } The problem with this is that if you pass it a sequence of wchar_t (say, from a wasting), it only encodes two hex digits per "character". -- Marshall Marshall Clow Idio Software <mailto:mclow.lists@gmail.com> A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait). -- Yu Suzuki

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Nov 2, 2011, at 1:32 PM, michi7x7 wrote:
Hi,
As Marshal pointed out, Spirit supports that easily
There are two 'll's at the end of my name, actually ;-)
sorry
Actually, it's not really difficult.
Nice!
Okay, I'm finished. Should be as generic as it gets ;-) Feel free to use it whenever you like. HTH michi7x7 -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.17 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iQEcBAEBAgAGBQJOsp0/AAoJEGzZyHoPGb6Hkc8H/ihXvkXYGUeFNiS0eniBMK/l U8QaBCxucbdgLcwskLZNqe/3JN8WD4qFI1aNhHhPkAb2ByavCHOcDdjiKpt/1XDP 35ZoX4dQyI08t+yqVjpGtB15MU8u0IBbqnq4N7sUPN2OiNzgcsPTE3qtxsFBlbKV 1nHG1xeQ1kPWJj6C25tLPozCcduSgzpQCzWJP7Vnh+6y0B0+3gkTjce6dbEk4psp 3Z7pEIK2WRkmLNTfRKx/NNc2MsjQmBDXhzOQhGR04uU6xk3xY/5hxOaAc9qndN0p DGQ1eafRfLd30Iqyf9SDGToFTR2Y2LZEo1RCsdwwzt3fcM4tQNSu5CsbsIy+5d4= =Vtpf -----END PGP SIGNATURE-----

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi
Okay, I'm finished. Should be as generic as it gets ;-) Feel free to use it whenever you like.
Marshall found a few bugs, which my MSVC didn't even notice... Here is a fixed version (I hope), what's still missing is a check if the whole input of unhex was parsed, which could be done by checking if first == last (thanks to spirit). HTH michi7x7 -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.17 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iQEcBAEBAgAGBQJOsq8DAAoJEGzZyHoPGb6HkDcIALnJlLeZoMIFIUTOtYP0hy84 bqU1Iz6NCTtwqo+LQxOXVwiD2Z5tXbtqjLGXRhGmq9XYXM9Cu40fn5IOCj09Cp+A 9eDfloZCi1PjRVUP3FoiWAN/0ytKhni/tJt7I2FZhGcPlIksvqS89XNb4o6J2FUi Nj8OpXOh2wZksQWJlUksBal5w1hlyQwhaG0bD8at5bppao2MSBeo1/RmT94KBg/8 kLKSQ9ung/cSXgQbPt4jLClc/ez31X8YJg5XiTh7UCQQpRz6CTR0qH5nYFhzV/pH ZBpIXDRltRIG1MInqzSj8ZPgQKarGDWnFDbpB3MvlSt1sBxc1Bekn71/3P3IxFY= =ia+V -----END PGP SIGNATURE-----

On Nov 3, 2011, at 8:11 AM, michi7x7 wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi
Okay, I'm finished. Should be as generic as it gets ;-) Feel free to use it whenever you like.
Marshall found a few bugs, which my MSVC didn't even notice... Here is a fixed version (I hope), what's still missing is a check if the whole input of unhex was parsed, which could be done by checking if first == last (thanks to spirit).
Works for me. And for comparison, here's a non-spirit version. -- Marshall Marshall Clow Idio Software <mailto:mclow.lists@gmail.com> A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait). -- Yu Suzuki

On Nov 1, 2011, at 1:09 PM, Olaf van der Spek wrote:
Does Boost have hex/unhex() that support std::string? I can't find them and I think they'd be quite handy to have.
Committed in revision 77138 -- Marshall Marshall Clow Idio Software <mailto:mclow.lists@gmail.com> A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait). -- Yu Suzuki

On Wed, Feb 29, 2012 at 12:19 AM, Marshall Clow <mclow.lists@gmail.com> wrote:
On Nov 1, 2011, at 1:09 PM, Olaf van der Spek wrote:
Does Boost have hex/unhex() that support std::string? I can't find them and I think they'd be quite handy to have.
Committed in revision 77138
Thanks. Got some questions though: What if input type is like range<char*> (and you'd like output type to be std::string)? I think output type and input type shouldn't be required to be equal. Should hex output be upper case or lower case? c++0x suggests lower case. :p Shouldn't hex_decode_error derive from std::runtime_error? Wouldn't it be simpler to only provide the range-based variant and require C strings and iterator pairs to be wrapped in a range? -- Olaf

On Jun 2, 2012, at 12:32 PM, Olaf van der Spek wrote:
On Wed, Feb 29, 2012 at 12:19 AM, Marshall Clow <mclow.lists@gmail.com> wrote:
On Nov 1, 2011, at 1:09 PM, Olaf van der Spek wrote:
Does Boost have hex/unhex() that support std::string? I can't find them and I think they'd be quite handy to have.
Committed in revision 77138
Thanks. Got some questions though: What if input type is like range<char*> (and you'd like output type to be std::string)? I think output type and input type shouldn't be required to be equal.
They don't have to be equal. std::string s; hex ( <range>, std::back_inserter (s));
Should hex output be upper case or lower case? c++0x suggests lower case. :p
Shouldn't hex_decode_error derive from std::runtime_error?
Yes, it probably should.
Wouldn't it be simpler to only provide the range-based variant and require C strings and iterator pairs to be wrapped in a range?
Simpler, yes. Easier to use, I think not. -- Marshall Marshall Clow Idio Software <mailto:mclow.lists@gmail.com> A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait). -- Yu Suzuki

On Sun, Jun 3, 2012 at 7:39 AM, Marshall Clow <mclow.lists@gmail.com> wrote:
What if input type is like range<char*> (and you'd like output type to be std::string)? I think output type and input type shouldn't be required to be equal.
They don't have to be equal. std::string s; hex ( <range>, std::back_inserter (s));
But that's not as convenient as the normal function which returns the string. It's also missing reserve(). Should hex output be upper case or lower case? c++0x suggests lower case. :p -- Olaf

On Jun 3, 2012, at 4:35 AM, Olaf van der Spek wrote:
On Sun, Jun 3, 2012 at 7:39 AM, Marshall Clow <mclow.lists@gmail.com> wrote:
What if input type is like range<char*> (and you'd like output type to be std::string)? I think output type and input type shouldn't be required to be equal.
They don't have to be equal. std::string s; hex ( <range>, std::back_inserter (s));
But that's not as convenient as the normal function which returns the string.
Indeed. My goal is not to provide every possible convenience function; the goal is to provide a functionality that can be used in a wide variety of circumstances. If you have a need for such a function, I am confident that you can write it.
It's also missing reserve().
reserve is not appropriate in this case; since in general, the size of the input range cannot be determined easily. For a null terminated string, you would have to traverse the input twice; once to determine the length, and the other to do the conversion. That might be advantageous (or not); but consider in the case where the input range is a pair of input iterators.
Should hex output be upper case or lower case? c++0x suggests lower case. :p
MySQL (and inertia) suggest upper case; note that unhex will accept both. -- Marshall Marshall Clow Idio Software <mailto:mclow.lists@gmail.com> A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait). -- Yu Suzuki

On 03/06/2012 14:20, Marshall Clow wrote:
Should hex output be upper case or lower case? c++0x suggests lower case. :p MySQL (and inertia) suggest upper case; note that unhex will accept both.
Would it be possible to specify the required behavior using std::uppercase/nouppercase manipulators? I'm thinking of an additional overload that works the way std::nothrow already does in certain language constructs. This would of course mean that the default should be lowercase, which I'd presume is the default for hex output on streams as well. Agustín K-ballo Bergé.- http://talesofcpp.blogspot.com

On Sun, Jun 3, 2012 at 7:20 PM, Marshall Clow <mclow.lists@gmail.com> wrote:
They don't have to be equal. std::string s; hex ( <range>, std::back_inserter (s));
But that's not as convenient as the normal function which returns the string.
Indeed.
Could you return a reference to the string to support chaining?
My goal is not to provide every possible convenience function; the goal is to provide a functionality that can be used in a wide variety of circumstances.
I think reference/view types like range<char*> and string_ref deserve direct support. This applies to all string functions, not just hex and unhex. Isn't it possible to have two template parameters Out and In where In is deduced and Out defaults to In?
It's also missing reserve().
reserve is not appropriate in this case; since in general, the size of the input range cannot be determined easily.
Lots of ranges have a known size. You could restrict support to such ranges.
For a null terminated string, you would have to traverse the input twice; once to determine the length, and the other to do the conversion. That might be advantageous (or not); but consider in the case where the input range is a pair of input iterators.
In that case the size can't be determined beforehand.
Should hex output be upper case or lower case? c++0x suggests lower case. :p
MySQL (and inertia) suggest upper case; note that unhex will accept both.
I think a parameter should be provided to choose between the two. Not providing a variant that doesn't throw on bad input is problematic too (IMO). A non-throwing variant should be available. A throwing variant can then be build on top of it. BTW, shouldn't hex be in the string directory? -- Olaf

On Mon, Jun 11, 2012 at 4:06 PM, Olaf van der Spek <ml@vdspek.org> wrote:
On Sun, Jun 3, 2012 at 7:20 PM, Marshall Clow <mclow.lists@gmail.com> wrote:
They don't have to be equal. std::string s; hex ( <range>, std::back_inserter (s));
But that's not as convenient as the normal function which returns the string.
Indeed.
Could you return a reference to the string to support chaining?
My goal is not to provide every possible convenience function; the goal is to provide a functionality that can be used in a wide variety of circumstances.
I think reference/view types like range<char*> and string_ref deserve direct support. This applies to all string functions, not just hex and unhex.
Isn't it possible to have two template parameters Out and In where In is deduced and Out defaults to In?
It's also missing reserve().
reserve is not appropriate in this case; since in general, the size of the input range cannot be determined easily.
Lots of ranges have a known size. You could restrict support to such ranges.
For a null terminated string, you would have to traverse the input twice; once to determine the length, and the other to do the conversion. That might be advantageous (or not); but consider in the case where the input range is a pair of input iterators.
In that case the size can't be determined beforehand.
Should hex output be upper case or lower case? c++0x suggests lower case. :p
MySQL (and inertia) suggest upper case; note that unhex will accept both.
I think a parameter should be provided to choose between the two.
Not providing a variant that doesn't throw on bad input is problematic too (IMO). A non-throwing variant should be available. A throwing variant can then be build on top of it.
BTW, shouldn't hex be in the string directory?
^ -- Olaf

On Jun 11, 2012, at 7:06 AM, Olaf van der Spek wrote:
Not providing a variant that doesn't throw on bad input is problematic too (IMO). A non-throwing variant should be available. A throwing variant can then be build on top of it.
No, it can not - because unhex has no control over the output iterator (which can throw).
BTW, shouldn't hex be in the string directory?
No. It's not a string algorithm. -- Marshall Marshall Clow Idio Software <mailto:mclow.lists@gmail.com> A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait). -- Yu Suzuki

On Tue, Jun 19, 2012 at 7:06 PM, Marshall Clow <mclow.lists@gmail.com> wrote:
On Jun 11, 2012, at 7:06 AM, Olaf van der Spek wrote:
Not providing a variant that doesn't throw on bad input is problematic too (IMO). A non-throwing variant should be available. A throwing variant can then be build on top of it.
No, it can not - because unhex has no control over the output iterator (which can throw).
Sure, but an unhex that doesn't throw on bad input would still be possible.
BTW, shouldn't hex be in the string directory?
No. It's not a string algorithm.
Where did my other questions go? -- Olaf
participants (7)
-
Agustín K-ballo Bergé
-
Hartmut Kaiser
-
Jeroen Habraken
-
Marshall Clow
-
michi7x7
-
Olaf van der Spek
-
Sergey Cheban