2002 2003 2004 <2005> 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 | Index | 2002 2003 2004 <2005> 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 |
<== Date ==> | <== Thread ==> |
---|
Subject: | Re: data access structures, strings |
From: | Andrew Johnson <[email protected]> |
To: | Jeff Hill <[email protected]> |
Cc: | [email protected] |
Date: | Tue, 27 Sep 2005 11:50:35 -0500 |
Jeff Hill wrote:
That interface does not have the numeric type read and write capabilities ala StringSegment so there is no way to perform string to numeric type conversion-in-place as is currently the case in data access support libraries.
See below.
virtual void assign(const StringReader & src, size_t pos = 0) = 0; virtual void assign(const char *str, size_t len) = 0;Given that StringReader has "extract(char *buf, size_t cap, size_t pos = 0)" and you (we) will presumably implement StringReader for all the important types of strings {std::string, string literals FixedString<int>, etc } I wonder why we need to force the string interfacing person to write "assign(const char *str, size_t len)" when its easy to use " assign(const StringReader & src, size_t pos = 0)" for the same purpose.
This is true and I would be willing to remove the second assign() function if that is the consensus, although the result means slightly more work for the user, and a performance hit: Constructing a ConstString from a const char* is an inline operation that requires three assignments into the string object (pointer, length, vtable); then the assignment operator for the target string has to call both the size() and extract() virtual methods on that ConstString. In my current implementation using an intermediate helper class the extract method itself calls its own size() which is a virtual call, and finally calls memcpy(). That's three virtual function calls that are not needed using the direct assignment function that calls memcpy() directly. If ConstString implemented its own extract() operation that number could reduce to two.
However going through a ConstString does slightly reduce the functionality that I'm providing - currently I regard a NULL char* pointer as an empty string, so you can assign() or append() one if you really want to and it won't throw an exception. However I don't permit you to construct a ConstString from a NULL pointer. This would also require the user to do the ConstString wrapping in their own code
As I mentioned above, I currently use an abstract helper class ConStringEditor which is derived from StringEditor to provide most of the API functions for contiguous strings, including the assign functions. ConStringEditor has three private pure virtual functions that permit it to get the buffer address and set the string size. I'm planning on an equivalent helper for segmented string types, but that's not very far on yet. These helper classes make implementing the string APIs much easier, since most implementations should be able to use them.
Here is some background on why I did what I did with StringSegment.
I think I managed to persuade you over the phone that there's not very much overhead and some advantages to implementing numeric conversions outside of the string classes themselves, using non-member non-friend functions that create a FixedString<n> buffer and use the standard C conversion routines.
- Andrew -- English probably arose from Normans trying to pick up Saxon girls.