
Hi, A lot of functions take a const void*, size_t pair as two parameters. This is then cast to a const unsigned char* for further processing. Two parameters means you can't easily pass the result of an expression or function call. One parameter would be handier. const std::string& is also used frequently. However, this forces the caller to use (or construct) std::string, which is undesirable and unnecessary. A solution seems simple: data_ref and string_ref, which represent a pointer pair (void/unsigned char and char respectively). string_ref can replace const std::string&, data_ref can replace const void*, size_t. I think this would be a nice addition to Boost. Is there any interest in a library that solves this problem? -- Olaf

On Tue, Mar 29, 2011 at 17:31, Olaf van der Spek <olafvdspek@gmail.com>wrote:
Hi,
A lot of functions take a const void*, size_t pair as two parameters. This is then cast to a const unsigned char* for further processing. Two parameters means you can't easily pass the result of an expression or function call. One parameter would be handier.
const std::string& is also used frequently. However, this forces the caller to use (or construct) std::string, which is undesirable and unnecessary.
A solution seems simple: data_ref and string_ref, which represent a pointer pair (void/unsigned char and char respectively). string_ref can replace const std::string&, data_ref can replace const void*, size_t.
I think this would be a nice addition to Boost. Is there any interest in a library that solves this problem?
-- Olaf _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
You already can use boost::iterator_range<const char*>. -- Yakov

On Tue, Mar 29, 2011 at 18:47, Olaf van der Spek <olafvdspek@gmail.com>wrote:
On Tue, Mar 29, 2011 at 5:40 PM, Yakov Galka <ybungalobill@gmail.com> wrote:
You already can use boost::iterator_range<const char*>.
It doesn't provide the interface const std::string& provides and it doesn't solve the case for const void* (I think).
-- Olaf
boost::iterator_range<const char*> is a sequence of bytes/chars, that is what pair<const void*,size_t> represents. It solves this case completely, but only that case. The reason it doesn't solve the const std::string& case is because there is no consensus of what interface std::string should have (see recent string discussions from about two months ago). As per the current std::string non-mutable interface, it includes only the find.* family of functions, substr, compare and c_str. Most of these are already handled by Boost.String and Boost.Range. They can work with interator_range transparently. The only problem is c_str, which I don't know how you want to implement it for string_ref anyway. -- Yakov

On Tue, Mar 29, 2011 at 7:07 PM, Yakov Galka <ybungalobill@gmail.com> wrote:
boost::iterator_range<const char*> is a sequence of bytes/chars, that is what pair<const void*,size_t> represents. It solves this case completely, but only that case.
Using const void* allows the callee to easily pass whatever he wants, using iterator_range<const unsigned char*> requires him to do an ugly cast. iterator_range also includes the terminator, which IMO is wrong.
The reason it doesn't solve the const std::string& case is because there is no consensus of what interface std::string should have (see recent string discussions from about two months ago). As per the current std::string
Will have a look.
non-mutable interface, it includes only the find.* family of functions, substr, compare and c_str. Most of these are already handled by Boost.String and Boost.Range. They can work with interator_range transparently. The only problem is c_str, which I don't know how you want to implement it for string_ref anyway.
c_str() can't be provided. -- Olaf

On 29/03/2011 19:24, Olaf van der Spek wrote:
On Tue, Mar 29, 2011 at 7:07 PM, Yakov Galka<ybungalobill@gmail.com> wrote:
boost::iterator_range<const char*> is a sequence of bytes/chars, that is what pair<const void*,size_t> represents. It solves this case completely, but only that case.
Using const void* allows the callee to easily pass whatever he wants, using iterator_range<const unsigned char*> requires him to do an ugly cast.
iterator_range also includes the terminator, which IMO is wrong.
iterator_range is a pair of iterators. In the case of iterator_range<const unsigned char*>, it's a pair of pointers. It only includes what you instruct it to. Use boost::as_literal to construct an iterator_range from a string literal.

On Tue, Mar 29, 2011 at 7:41 PM, Mathias Gaunard <mathias.gaunard@ens-lyon.org> wrote:
Using const void* allows the callee to easily pass whatever he wants, using iterator_range<const unsigned char*> requires him to do an ugly cast.
iterator_range also includes the terminator, which IMO is wrong.
iterator_range is a pair of iterators. In the case of iterator_range<const unsigned char*>, it's a pair of pointers.
It only includes what you instruct it to.
Use boost::as_literal to construct an iterator_range from a string literal.
Before: void f(const string&); f("Olaf"); After: void f(string_ref); f("Olaf"); I do not want to change the API and I certainly don't want callers to have to use boost::as_literal around every literal. -- Olaf

On 29/03/2011 19:51, Olaf van der Spek wrote:
On Tue, Mar 29, 2011 at 7:41 PM, Mathias Gaunard <mathias.gaunard@ens-lyon.org> wrote:
Using const void* allows the callee to easily pass whatever he wants, using iterator_range<const unsigned char*> requires him to do an ugly cast.
iterator_range also includes the terminator, which IMO is wrong.
iterator_range is a pair of iterators. In the case of iterator_range<const unsigned char*>, it's a pair of pointers.
It only includes what you instruct it to.
Use boost::as_literal to construct an iterator_range from a string literal.
Before: void f(const string&); f("Olaf"); After: void f(string_ref); f("Olaf");
I do not want to change the API and I certainly don't want callers to have to use boost::as_literal around every literal.
Then do struct string_range : boost::iterator_range<const char*> { string_range(const char* s) : boost::iterator_range<const char*>(boost::as_literal(s)) { } string_range(const char* first, const char* last) : boost::iterator_range<const char*>(first, last) { } };

On Tue, Mar 29, 2011 at 8:01 PM, Mathias Gaunard <mathias.gaunard@ens-lyon.org> wrote:
Use boost::as_literal to construct an iterator_range from a string literal.
Before: void f(const string&); f("Olaf"); After: void f(string_ref); f("Olaf");
I do not want to change the API and I certainly don't want callers to have to use boost::as_literal around every literal.
Then do
struct string_range : boost::iterator_range<const char*> { string_range(const char* s) : boost::iterator_range<const char*>(boost::as_literal(s)) { }
string_range(const char* first, const char* last) : boost::iterator_range<const char*>(first, last) { } };
You don't want to repeat that bit of code in every app / lib you write. -- Olaf

On Tue, Mar 29, 2011 at 7:07 PM, Yakov Galka <ybungalobill@gmail.com> wrote:
The reason it doesn't solve the const std::string& case is because there is no consensus of what interface std::string should have (see recent string discussions from about two months ago). As per the current std::string
Isn't that discussion about an entirely different thing? -- Olaf

On 2011-03-29 17:31, Olaf van der Spek wrote:
Hi,
A lot of functions take a const void*, size_t pair as two parameters. This is then cast to a const unsigned char* for further processing. Two parameters means you can't easily pass the result of an expression or function call. One parameter would be handier.
const std::string& is also used frequently. However, this forces the caller to use (or construct) std::string, which is undesirable and unnecessary.
A solution seems simple: data_ref and string_ref, which represent a pointer pair (void/unsigned char and char respectively). string_ref can replace const std::string&, data_ref can replace const void*, size_t.
I think this would be a nice addition to Boost. Is there any interest in a library that solves this problem?
Asio's buffer-handling concepts and classes might be what you are looking for? Cheers, Rutger

On Tue, Mar 29, 2011 at 7:07 PM, Rutger ter Borg <rutger@terborg.net> wrote:
On 2011-03-29 17:31, Olaf van der Spek wrote:
Hi,
A lot of functions take a const void*, size_t pair as two parameters. This is then cast to a const unsigned char* for further processing. Two parameters means you can't easily pass the result of an expression or function call. One parameter would be handier.
const std::string& is also used frequently. However, this forces the caller to use (or construct) std::string, which is undesirable and unnecessary.
A solution seems simple: data_ref and string_ref, which represent a pointer pair (void/unsigned char and char respectively). string_ref can replace const std::string&, data_ref can replace const void*, size_t.
I think this would be a nice addition to Boost. Is there any interest in a library that solves this problem?
Asio's buffer-handling concepts and classes might be what you are looking for?
Yes, those appear to be close to the required functionality. I'll have a look. -- Olaf
participants (4)
-
Mathias Gaunard
-
Olaf van der Spek
-
Rutger ter Borg
-
Yakov Galka