Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

A fixed string

56 views
Skip to first unread message

woodb...@gmail.com

unread,
Jul 4, 2017, 10:41:49 PM7/4/17
to
There's const_string:
http://conststring.sourceforge.net/

and fix_str:
https://www.codeproject.com/articles/12024/fix-str-an-almost-immutable-string-class-in-c

I'm not sure why something like this hasn't been more popular,
so I decided to give it a shot also. Small string optimization
goes up to around 24 characters I think. I think this could be
helpful for cases that are bigger than that.

Please let me know what you think about it. I may add some
assignment operators.


#pragma once
#include"ErrorWords.hh"
#include"marshalling_integer.hh"
#include"SendBuffer.hh"
#include<array>
#include<string_view>
#include<string.h>

namespace cmw{

template<int N>
class fixed_string{
int length;
::std::array<char,N> str;

public:
explicit fixed_string (char const* s):length(::strlen(s)){
if(length>N-1)throw failure("fixed_string ctor");
::strcpy(&str[0],s);
}


 explicit fixed_string (string_view s):length(s.length())){
if(length>N-1)throw failure("fixed_string ctor");
::strncpy(&str[0],s.data(),length);
str[length]='\0';
}

template<class R>
explicit fixed_string (ReceiveBuffer<R>&buf):length(
marshalling_integer(buf)()){
if(length>N-1)throw failure("fixed_string stream ctor");
buf.Give(&str[0],length);
str[length]='\0';
}


 void Marshal (SendBuffer& buf,bool=false)const{
marshalling_integer(length).Marshal(buf);
buf.Receive(&str[0],length);
}


 char const* c_str ()const {return &str[0];}
char operator[] (int index)const {return str[index];}
};

using fixed_string_60 = fixed_string<60>;
using fixed_string_120 = fixed_string<120>;
}


I haven't checked this in yet, but probably will over here:
https://github.com/Ebenezer-group/onwards


Brian
Ebenezer Enterprises - Enjoying programming again.
http://webEbenezer.net

Marcel Mueller

unread,
Jul 5, 2017, 1:32:43 AM7/5/17
to
On 05.07.17 04.41, woodb...@gmail.com wrote:
> There's const_string:
> http://conststring.sourceforge.net/
>
> and fix_str:
> https://www.codeproject.com/articles/12024/fix-str-an-almost-immutable-string-class-in-c
>
> I'm not sure why something like this hasn't been more popular,
> so I decided to give it a shot also. Small string optimization
> goes up to around 24 characters I think. I think this could be
> helpful for cases that are bigger than that.
>
> Please let me know what you think about it. I may add some
> assignment operators.

I never used any of the above. But I already used immutable string
classes in larger projects.

Well I think that strings of statically typed size are of little use
unless you intend to port very old code from Cobol or something similar.

On the other side /immutable/ strings /are/ very useful, especially in
multi-threaded environments because they are intrinsically thread-safe
for read operations.

But if you talk about immutable strings you need always talk about
/mutable/ string references, too. They are essential to use the
immutable strings. They provide the object lifetime management. And, of
course, they are /not/ intrinsically thread-safe.
Most of the time the programmer will deal with these string references
rather than the internal string behind the scenes.

Writing an immutable string class is straight forward. But writing a
reasonably smart, mutable wrapper around the string references /is/ an
advanced topic, at least if you include thread-safety with reasonable
performance.

The basic idea behind this concept is to keep any non-mutating
operations to the strings content constant time, including assignment
(of the references) and including thread-safe read and write of the
references.
In fact it can be implemented lock-free and even without CAS loops or
spin-locks. BTDT

If you have gone this way it opens the door to deduplication of string
values in memory and in memory database applications with rather high
performance. BTDT, too.


Marcel

peter koch

unread,
Jul 5, 2017, 5:01:52 AM7/5/17
to
Den onsdag den 5. juli 2017 kl. 07.32.43 UTC+2 skrev Marcel Mueller:
> On 05.07.17 04.41, woodb...@gmail.com wrote:
> > There's const_string:
> > http://conststring.sourceforge.net/
> >
> > and fix_str:
> > https://www.codeproject.com/articles/12024/fix-str-an-almost-immutable-string-class-in-c
> >
> > I'm not sure why something like this hasn't been more popular,
> > so I decided to give it a shot also. Small string optimization
> > goes up to around 24 characters I think. I think this could be
> > helpful for cases that are bigger than that.
>
> Well I think that strings of statically typed size are of little use
> unless you intend to port very old code from Cobol or something similar.

Why? I guess it very much depends on your application area.
Personally, I have much use of strings with a static maximum size, using them whenever I program against an interface which defines maximum sizes for I/O.
This enables me to verify my strings size at creation rather than when I need to serialise it (putting it on a display or sending it over a wire).

Internally, my size-limited strings are represented as a std::(w)string or as a boost::small_vector (if I remember the name correctly).

The same is the case for any array I use representing "external" data.

>
> On the other side /immutable/ strings /are/ very useful, especially in
> multi-threaded environments because they are intrinsically thread-safe
> for read operations.
>
> Marcel
Certainly! Immutable and hopefully also constexpr so that I can manipulate them while compiling.

/Peter

Dombo

unread,
Jul 5, 2017, 2:03:50 PM7/5/17
to
Op 05-Jul-17 om 7:32 schreef Marcel Mueller:

> On the other side /immutable/ strings /are/ very useful, especially in
> multi-threaded environments because they are intrinsically thread-safe
> for read operations.
>
> But if you talk about immutable strings you need always talk about
> /mutable/ string references, too. They are essential to use the
> immutable strings. They provide the object lifetime management. And, of
> course, they are /not/ intrinsically thread-safe.
> Most of the time the programmer will deal with these string references
> rather than the internal string behind the scenes.
>
> Writing an immutable string class is straight forward. But writing a
> reasonably smart, mutable wrapper around the string references /is/ an
> advanced topic, at least if you include thread-safety with reasonable
> performance.
>
> The basic idea behind this concept is to keep any non-mutating
> operations to the strings content constant time, including assignment
> (of the references) and including thread-safe read and write of the
> references.
> In fact it can be implemented lock-free and even without CAS loops or
> spin-locks. BTDT
>
> If you have gone this way it opens the door to deduplication of string
> values in memory and in memory database applications with rather high
> performance. BTDT, too.

In many programming languages such as C#, Java and Python strings are
immutable, which is a very useful property indeed. It would be a nice if
standard library supplied a immutable string class of its own.



Marcel Mueller

unread,
Jul 5, 2017, 2:46:28 PM7/5/17
to
On 05.07.17 11.01, peter koch wrote:
>> Well I think that strings of statically typed size are of little use
>> unless you intend to port very old code from Cobol or something similar.
>
> Why? I guess it very much depends on your application area.
> Personally, I have much use of strings with a static maximum size, using them whenever I program against an interface which defines maximum sizes for I/O.

A static *maximum* size is helpful, indeed.
But AFAICS the example always allocated the maximum size. This is big
waste of memory unless the limit is only a few bytes.


>> On the other side /immutable/ strings /are/ very useful, especially in
>> multi-threaded environments because they are intrinsically thread-safe
>> for read operations.
>>
>> Marcel
> Certainly! Immutable and hopefully also constexpr so that I can manipulate them while compiling.

Well, this is an even more advanced topic, since the restrictions for
constexpr are quite tight. I don't think that a string class can have a
/runtime/ dynamic length and constexpr (factory) functions at the same
time, at least not with C++11.

I had a similar requirement years ago. I.e. neither the string class
constructors of program constants should invoke dynamic allocations at
program startup, nor a dynamic allocation and string copying should
happen every time the constant is accessed. In fact no copying of the
constant data should be done at all.
I ended up with a distinct class for this purpose. This one had the
string length in the type and used the internal data structures of the
'normal' string class in a way that prevented the deallocator from
running so it could bind to static storage rather than heap storage.

It should be possible to write a class for your requirements that is
compatible to the matching immutable string class.


Marcel

peter koch

unread,
Jul 5, 2017, 3:15:30 PM7/5/17
to
Den onsdag den 5. juli 2017 kl. 20.46.28 UTC+2 skrev Marcel Mueller:
> On 05.07.17 11.01, peter koch wrote:
> >> Well I think that strings of statically typed size are of little use
> >> unless you intend to port very old code from Cobol or something similar.
> >
> > Why? I guess it very much depends on your application area.
> > Personally, I have much use of strings with a static maximum size, using them whenever I program against an interface which defines maximum sizes for I/O.
>
> A static *maximum* size is helpful, indeed.
> But AFAICS the example always allocated the maximum size. This is big
> waste of memory unless the limit is only a few bytes.
>
I do not know which example you are referring to. In my code, I simply choose between boost::container::static_vector and std::vector dependent on the maximum number of elements.
When max_size < threshold/sizeof(T), I choose the static vector. threshold is currently defined as sizeof(std::string) and this seems like a reasonable default, assuming the compiler-folks have taken their time to decide on a proper size for SSO.

For compile-time strings you want a newer compiler, at least C++14. And not Microsofts right now.

woodb...@gmail.com

unread,
Jul 7, 2017, 10:25:27 AM7/7/17
to
On Wednesday, July 5, 2017 at 4:01:52 AM UTC-5, peter koch wrote:
> Den onsdag den 5. juli 2017 kl. 07.32.43 UTC+2 skrev Marcel Mueller:
> >
> > Well I think that strings of statically typed size are of little use
> > unless you intend to port very old code from Cobol or something similar.
>
> Why? I guess it very much depends on your application area.
> Personally, I have much use of strings with a static maximum size, using them whenever I program against an interface which defines maximum sizes for I/O.
> This enables me to verify my strings size at creation rather than when I need to serialise it (putting it on a display or sending it over a wire).
>
> Internally, my size-limited strings are represented as a std::(w)string or as a boost::small_vector (if I remember the name correctly).

Thanks for the reminder of this class. By the grace
of G-d, I've now added support for small_vector to the
C++ Middleware Writer.

I wish this class was available more like plf::colony.
Colony is easy_to_work_with.


Brian
Ebenezer Enterprises
http://webEbenezer.net

bitrex

unread,
Jul 7, 2017, 10:37:42 AM7/7/17
to
On 07/04/2017 10:41 PM, woodb...@gmail.com wrote:
> There's const_string:
> http://conststring.sourceforge.net/
>
> and fix_str:
> https://www.codeproject.com/articles/12024/fix-str-an-almost-immutable-string-class-in-c
>
> I'm not sure why something like this hasn't been more popular,
> so I decided to give it a shot also. Small string optimization
> goes up to around 24 characters I think. I think this could be
> helpful for cases that are bigger than that.
>
> Please let me know what you think about it. I may add some
> assignment operators.

I wrote something similar to that for use in embedded environments; it's
a little different in that my version uses a linked-list custom
allocator that plops std::strings (also using the allocator, allocating
blocks for characters within the blocks for whole strings) into a static
memory buffer that's created at startup. So say you can have a
"fixed_string<5, 60>" which will let you hold up to 5 strings of up to
60 characters each in memory that you can freely create, destroy, and
assign to each other cheaply (IIRC assignment is just moving a pointer
around) and do most of the usual string operations on without ever
needing to dynamically allocate memory from the heap

Bonita Montero

unread,
Jul 8, 2017, 4:38:51 PM7/8/17
to
What I't to find to be cooler would be a string-class with a template
parameter that specifies an amount of static storage in the class up
to which the string-content will be assigned to. And If the string is
larger, it would be allocated on the heap. Of course such a class would
be useful almost only for stack-allocated string because it would blow
up objects that contain such strings on heap.
0 new messages