0

I am looking for a string implementation with fixed upper size that can be used in memcopy environment and that is trivially constructible and copyable.

I found boost beast static_string, but IDK if my example works by accident or no?

#include <algorithm>
#include <iostream>
#include <boost/beast/core/static_string.hpp>
boost::beast::static_string<16> s1("abc");

int main(){
    boost::beast::static_string<16> s2;
    std::copy_n((char*)&s1, sizeof(s2), (char*)&s2);
    s1.push_back('X');
    std::cout << "--" << std::endl;
    std::cout << s2 << std::endl;
    s2.push_back('Y');
    std::cout << s2 << std::endl;
    std::cout << std::is_trivial_v<decltype(s2)> << std::endl;
}

note: last line says type is not trivially copyable, but it could be just that Vinnie forgott to add a type trait.

P.S. I know this is a generally bad idea, what I am replacing is even worse, just a plain C array and modifying the allocation/copying to support std::string is much much more work.

NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
  • 3
    how about `std::array` ? – 463035818_is_not_an_ai Mar 09 '20 at 09:41
  • @idclev463035818 it is not user friendly, eg no push_back. – NoSenseEtAl Mar 09 '20 at 09:51
  • yes realized that this is a requirement, but still wrapping a array to turn its `size` into a `capacity` is probably still easier than getting `std::string` to work as you wish – 463035818_is_not_an_ai Mar 09 '20 at 09:53
  • @idclev463035818 I know std::string does not work, my question is about beast static_string – NoSenseEtAl Mar 09 '20 at 09:54
  • 1
    I know, I didnt attempt to answer your question – 463035818_is_not_an_ai Mar 09 '20 at 09:55
  • _but it could be just that Vinnie forgott to add a type trait_ — No, that's not the reason. `static_string` has a [user-provided copy constructor](https://github.com/boostorg/beast/blob/develop/include/boost/beast/core/impl/static_string.hpp#L85), therefore it cannot be a trivially-copyable type. – Daniel Langr Mar 09 '20 at 09:58
  • @DanielLangr thank you. Does type_traits have some other way for lib authors to signal their type can be memcopied and constructed without running a constructor? – NoSenseEtAl Mar 09 '20 at 10:03
  • @NoSenseEtAl Why some other way? Either a type is trivially-copyable or isn't. If the type trait can find out this automatically, there is no reason for any "signals from outside". – Daniel Langr Mar 09 '20 at 10:13
  • @DanielLangr my question is: If library author wants to give answer to my questions(can I memcpy/ assume malloced class is properly constructed) does c++ give him any way to signal that with type traits? – NoSenseEtAl Mar 09 '20 at 10:29
  • 1
    @NoSenseEtAl Sorry, but still don't understand. Classes are trivially-copyable if they satisfy some [conditions posed by the C++ Standard](http://eel.is/c++draft/class.prop#1). They are not trivially-copyable because of type traits or some "signals". The type trait is only a way how to find out. In other words, you "signal" the trivial-copyability by the way how a class is designed. – Daniel Langr Mar 09 '20 at 10:39
  • @DanielLangr well that sucks... And about what I was asking: I was asking if the class author can say something about semantics of the class using c++. Apparently not. – NoSenseEtAl Mar 09 '20 at 10:42

1 Answers1

3

Technically no, there are user defined copy constructors and operators (both call assign) which mean the class is not trivially copyable.

These appear to exist as an optimisation, if a static_string has a large size, but only stores a small string, assign only copies the used portion of the string, plus a null terminator.

C++ does not allow for std::is_trivially_copyable to be specialized by programs, so I don't believe there is a way to get both at present.

static_string does just contain a size_t member and a CharT[N+1], so if those two were default, it would be.

Fire Lancer
  • 29,364
  • 31
  • 116
  • 182
  • 1
    it is not allowed to specialize any trait of that family (`is_trivial`, `is_default_constructible`, etc), does that mean that one does not have to add specializations, because the compiler can detect those properties? When trying to find the answer I turned in circles, didnt find a trait that is not defined in terms of some other trait – 463035818_is_not_an_ai Mar 09 '20 at 11:06