Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: sf::String removal  (Read 4438 times)

0 Members and 1 Guest are viewing this topic.

Disch

  • Full Member
  • ***
  • Posts: 220
    • View Profile
sf::String removal
« on: August 15, 2011, 10:18:41 pm »
sf::String suffers from "another string class" syndrome.

It's true that it adds handy conversion and locale functionality, but when it comes to other fundamental features of a typical string class (like std::string), it falls short.

I don't think increasing sf::String functionality is the solution.  I think that would only serve to be extra work and write code that already exists in the standard library.

Instead, I think sf::String should be removed entirely.  And instead, all the conversion and locale functionality it offers should be placed in a separate series of global utility functions that operate on external objects (rather than trying to manage the string data themselves).

With such conversion functions in place, instances of sf::String could be replaced with std::basic_string<sf::Uint32>.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
sf::String removal
« Reply #1 on: August 15, 2011, 10:33:22 pm »
True, true and true.

But! The conversion functions already exist (see sf::Utf), in fact sf::String is a layer on top of them to provide automatic conversions.

The problem with std::basic_string<sf::Uint32> is that it's not convenient to use. Trust me, I've thought about this problem a lot, and although I don't like the sf::String class, sadly it's the most convenient solution.
Laurent Gomila - SFML developer

Disch

  • Full Member
  • ***
  • Posts: 220
    • View Profile
sf::String removal
« Reply #2 on: August 15, 2011, 11:30:15 pm »
Gah I had a big post here but my connection swallowed it.

sf::Utf fits the bill, but lacks direct support for strings.  The iterator interface is good, but I think another layer could be put on top of that.

Currently, if you want to use sf::Utf to convert a string, it's a multi-step process that is very unintuitive for beginners:

Code: [Select]

std::string my8; // utf8 string
std::wstring my16; // utf16 string

// we want to convert my16 to my8

my8.resize( X );  // where 'X' is big enough to hold a my16 in UTF8 form.
std::string::iterator stop = sf::Utf<16>::ToUtf8( my16.begin(), my16.end(), my8.begin() );
my8.resize( stop - my8.begin() );


Not only is that overly complicated, but it's also error prone.  The user shouldn't be expected to calculate X.  That should be up to the conversion routine.  There's not even any way to guard against potential overflow here, if X is calculated incorrectly.

I'd like to see something like this:

Code: [Select]

// simple:
my8 = sf::ToUtf8(my16);

// this would work too, but it's too verbose for my taste:
my8 = sf::Utf<16>::ToUtf8(my16);



With these kinds of conversion routines not fixed to any one class, the need for sf::String dissolves and can be replaced with std::basic_string.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
sf::String removal
« Reply #3 on: August 15, 2011, 11:38:05 pm »
Quote from: "Disch"
Not only is that overly complicated, but it's also error prone.  The user shouldn't be expected to calculate X.
Use std::back_inserter ;)

The iterator approach is very flexible, for example for transforming only parts of strings or other containers holding characters. I don't consider it a good idea to lose this genericity. At the moment, you can still perform the conversion in a very simple way via sf::String.

Quote from: "Disch"
With these kinds of conversion routines not fixed to any one class, the need for sf::String dissolves and can be replaced with std::basic_string.
Not really. For example, you can't initialize std::basic_string<sf::Uint32> with string literals, what makes code like sf::Text::SetString() calls unnecessarily complicated. There are always explicit conversions necessary, which aren't very beginner-friendly, either.

Apart from that, std::basic_string<sf::Uint32> partially suffers from the "another string class" syndrome, too, since no code apart from SFML projects uses it. The interface may be known to users of std::string, but the compatibility to standard strings is nevertheless limited.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Disch

  • Full Member
  • ***
  • Posts: 220
    • View Profile
sf::String removal
« Reply #4 on: August 15, 2011, 11:47:39 pm »
Quote from: "Nexus"
Use std::back_inserter ;)


Ah.  Nice.

Still, you'd want to calculate X for a reserve() call at least to avoid unnecessary reallocation.

Quote
A simpler solution would probably not be bad, but the iterator approach is very flexible, for example for transforming only parts of strings or other containers holding characters.


I agree completely.  The iterator solution is great and should not be removed.  I just think there should be something simpler for common tasks.

Quote
At the moment, you can still perform the conversion in a very simple way via sf::String.


But that involves the overhead of copying the string to an intermediate buffer.  If you're using sf::String solely for the conversion, it doesn't make sense for it to keep a copy of the string buffered.  That's kind of why I think it should be removed.

Quote from: "Disch"
Not really. For example, you can't initialize std::basic_string<sf::Uint32> with string literals, what makes code like sf::Text::SetString() calls unnecessarily complicated.


There are solutions for this besides having another string class.  The most obvious is to give SetString more overloads.

Although maybe a better option would be to have a conversion class that doesn't buffer the string.  That way you could still have implicit casts but without the need for the additional buffering.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
sf::String removal
« Reply #5 on: August 15, 2011, 11:54:53 pm »
Quote from: "Disch"
But that involves the overhead of copying the string to an intermediate buffer.
That is true, but at least it is simple ;)

Most people, especially beginners, won't need the speed. Those who do are certainly able to write a wrapper around the UTF iterator transformations.

Quote from: "Disch"
There are solutions for this besides having another string class.  The most obvious is to give SetString more overloads.
And produce enormous code duplication by doing that everywhere SFML takes a string? And the next point is even more interesting: What do you do with GetString()? You can't overload that.

Quote from: "Disch"
Although maybe a better option would be to have a conversion class that doesn't buffer the string. That way you could still have implicit casts but without the need for the additional buffering.
The most elegant solution would probably be to enable move semantics for sf::String. Or at least to provide move-friendly C++98 code (e.g. parameters by value, that are swapped internally), so that the user is able to take advantage of std::move().

Edit: I just realized the last paragraph doesn't work, since sf::String first copies the characters to its own buffer, instead of directly adopting the string.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Disch

  • Full Member
  • ***
  • Posts: 220
    • View Profile
sf::String removal
« Reply #6 on: August 16, 2011, 12:08:18 am »
You make good points.  This will take more thought.

I've been wrestling with how to approach this topic with my own project.  I originally decided on sf::String, but using it for anything other than conversion (ie:  finding, replacing substrings, etc) becomes a real chore.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
sf::String removal
« Reply #7 on: August 16, 2011, 08:41:59 am »
Well, the real problem here is that:
- the standard library lacks a Unicode string class
- the standard library's design is not optimal, it would be better if it was using free generic functions for find/substr/replace/... therefore, anything with begin() and end() functions would be a suitable string class
Laurent Gomila - SFML developer

vanisher

  • Newbie
  • *
  • Posts: 7
    • View Profile
sf::String removal
« Reply #8 on: September 13, 2011, 11:07:08 pm »
One helluva string class is glib::ustring (from gtkmm), all UTF-8 and a fine string formatter included. Fully exchangeable with std::string. I wish C++0x would just add that class to the STL. My 2 cents..

 

anything