* Alf P. Steinbach:
Reusing most of the text I posted for the 01 and 02 versions:
An 04 version of StringValue is now available at
<url:
http://home.no.net/alfps/cpp/lib/alfs_v04.zip>.
Old features:
* A StringValue can be constructed from a literal in constant
time with no dynamic allocation.
* A StringValue can be constructed from a pointer and deletion
operation (functor or function) in constant time, with no O(n)
copying.
* A StringValue can be copied and assigned in constant time with
no dynamic allocation (great for e.g. standard containers).
* A StringValue can be safely constructed in other ways, including
from a 'char const*' and from a 'std::string', but then involving
O(n) copying and dynamic allocation.
* A StringValue can be freely copied and assigned, but the value
can not be modified.
* A license reference (Boost license) is included in every file,
resulting from comments by Roland Pibinger (thanks).
* operator==, operator< added,
resulting from comments by Barry <
[email protected]> (thanks).
* Implicit conversion to 'char const*' /removed/, because
* A class StringValueOrNull was added, which supports passing
null-values around. A StringValue is implicitly convertible to
StringValueOrNull. A StringValueOrNull value can only be explicitly
converted to pure StringValue, then with checking of nullvalue &
possible exception.
* Support for << and >> stream i/o added (because of removal of
implicit conversion to 'char const*').
* In order to be useful in Windows programming, wchar_t versions of
StringValue (WStringValue) and StringValueOrNull (ditto) have
been added, i.e. templatization on the character type.
* Free function swap implementations moved from namespace std to
namespace alfs, resulting from comments by Greg Herlihy (thanks).
* Two small example usage programs, one an abstraction of the 'main'
arguments (with almost no overhead), and one ditto showing a simple
abstraction of Windows Unicode command line arguments.
New features:
* Templatized streaming operators (i.e. wide character streaming),
resulting from comments by Barry <
[email protected]> (thanks).
* Basic tied string functionality.
* Indexing operator for SharedArray (yeah, finally).
A /tied string/ shares its reference counting with some specified
SharedArray, using that SharedArray as a lifetime manager. One useful
application is for constant time substring extraction. However,
constant time substring extraction requires some more machinery than
currently present (namely keeping track of string lengths).
For now, example code abstracting Windows Unicode program arguments:
<code>
// "Error handling omitted for brevity & clarity".
#include <alfs/StringValueClass.hpp>
#include <cstddef> // std::size_t, std:
trdiff_t
#include <vector> // std::vector
#include <string> // std::wstring
#define UNICODE
#define _UNICODE
#include <windows.h>
class ProgramArguments
{
// A ProgramArguments instance can be copied freely in constant time.
// And it can be destroyed while still having individual StringValue
// argument instances around (the CommandLineToArgvW result is then
// freed only when all argument StringValue instances destroyed).
private:
typedef alfs::SharedArray<wchar_t*> StringPtrArray;
StringPtrArray myArgPointers;
int myArgCount;
public:
typedef std:
trdiff_t Index;
ProgramArguments()
{
wchar_t** const argPointers = CommandLineToArgvW(
GetCommandLine(), &myArgCount
);
myArgPointers = StringPtrArray( argPointers, GlobalFree );
}
std::size_t size() const
{
return myArgCount;
}
alfs::StringValue operator[]( Index i ) const
{
// Constant time, no dynamic allocation.
using namespace alfs;
return StringValue(
TiedPointer(), myArgPointers
, myArgPointers
);
}
};
void cppMain(
alfs::StringValue const& commandLine,
ProgramArguments const& arguments
)
{
std::wstring s = commandLine.pointer();
s += L'\n';
for( std::size_t i = 0; i < arguments.size(); ++i )
{
s += L'\n';
s += arguments.cStr();
}
wchar_t const title[] =
L"Command line & std arguments interpretation:";
MessageBox( 0, s.c_str(), title, MB_ICONINFORMATION );
}
alfs::StringValue commandLine()
{
// Client code need not distinguish between this static pointer and
// some string that needs deallocation.
return alfs::StringValue( GetCommandLine(), alfs::NoDelete() );
}
int main()
{
cppMain( commandLine(), ProgramArguments() );
// Almost no per-string overhead.
}
</code>
Comments, ideas, criticism etc. welcome! Note: almost not tested code.
At least not formally tested!
Cheers, & hope this can be interesting,
- Alf
(still hoping SomeOne(TM) can do the honors of testing speed, e.g.
sorting a large vector of std::string versus BStringType!)