Giter Site home page Giter Site logo

boostorg / static_string Goto Github PK

View Code? Open in Web Editor NEW
59.0 9.0 32.0 640 KB

A fixed capacity dynamically sized string

Home Page: http://boost.org/libs/static_string

License: Boost Software License 1.0

CMake 0.79% C++ 95.45% HTML 0.12% Shell 1.41% Starlark 2.12% Batchfile 0.11%
boost string cplusplus embedded

static_string's Introduction

Boost.StaticString

Branch Travis Appveyor Azure Pipelines codecov.io Docs Matrix
master Build Status Build status Build Status codecov Documentation Matrix
develop Build Status Build status Build Status codecov Documentation Matrix

Introduction

This library provides a dynamically resizable string of characters with compile-time fixed capacity and contiguous embedded storage in which the characters are placed within the string object itself. Its API closely resembles that of std::string.

Documentation

License

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)

static_string's People

Contributors

alandefreitas avatar eldiener avatar evanlenz avatar glenfe avatar grisumbras avatar pdimov avatar sdarwin avatar sdkrystian avatar vinniefalco avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

static_string's Issues

Update CI

static_string needs the same treatment as Boost.JSON: Update the CI scripts to check msvc versions 14.0, 14.1, and 14.2 on Drone. Remove Appveyor and Travis badges and scripts if they are not already removed.

`static_wstring` should be conditionally enabled

Hi!

static_wstring fails to compile on platforms that don't have libc support
for wide-character strings. I got it to work by defining a no-op
std::swprintf(...), but obviously that isn't really a solution.

However, boost::config has feature detection macros for this: BOOST_NO_CWCHAR
and BOOST_NO_SWPRINTF. So ideally, static_wstring should be conditionally
enabled based on those.

Compilation error under c++20 with constexpr

Hello,

I have compilation errors for the following code:

#include <iostream>
#include <boost/static_string.hpp>

constexpr auto getString()
{
    boost::static_strings::static_string<1024> content;
    content.append("Hello world");
    return content;
}

constexpr auto msg = getString();

int main()
{
    std::cout << msg.c_str() << std::endl;
    return 0;
}

The code fails to compile under:

  • clang 13.1.6
  • VS2022 17.2.6

The walk around I've found is to allow an array initialisation of static_string_base class, meaning replacing:

#ifdef BOOST_STATIC_STRING_CPP20
    value_type data_[N + 1];
#else
    value_type data_[N + 1] {};
#endif

with

    value_type data_[N + 1] {};

Add static_string variant without extra space overhead

Current design doesn't guarantee anything about space occupied by static_string<N>. User can't assume that sizeof(basic_static_string<N, CharT>) == (N+1) * sizeof(CharT) (nor sizeof(basic_static_string<N, CharT>) == N * sizeof(CharT) as N doesn't take final null-terminator into account) because the class stores additional size_ field. This is a good thing for std::string compatibility which doesn't assume that stored string can't have null characters.

On the other hand, there are still situations where null-terminated cstring-wrapper could be handy. To show the example, we can have a pseudo-POD structure with standarized layout:

struct user_pod
{
  std::uint32_t id;
  char name[64];
  std::uint32_t something;
};

Such structures requires using non-modern C functions (like std::strncpy) to fill it. This could be replaced with something more handy:

struct user_pod
{
  std::uint32_t id;
  boost::cstring<63> name;
  std::uint32_t something;
};

...where boost::cstring is a working name of a hypothetical specific class with a strong guaranty that underlying object stores only a CharT array of size N+1 (or N, depending on further design) and therefore that objects of that class are trivially copyable.

Implementation of such class doesn't seem to be a hard work - most of existing code could be reused, only static_string_base should be conditional. To ilustrate possible design:

Wandbox link

#include <iostream>
#include <cstring>

namespace boost {

namespace detail {

template<std::size_t N, typename CharT, typename Traits>
class static_string_base
{
  using traits_type = Traits;
  using value_type = typename traits_type::char_type;
  using size_type = std::size_t;
public:
  std::size_t size_impl() const noexcept
  {
    return size_;
  }
private:
    size_type size_ = 0;
    value_type data_[N + 1]{};
};

template<std::size_t N, typename CharT, typename Traits>
class static_nullterminated_string_base
{
    using traits_type = Traits;
    using value_type = typename traits_type::char_type;
public:
  std::size_t size_impl() const noexcept
  {
    return traits_type::length(data_);
  }
private:
    value_type data_[N + 1]{};
};
    
} // namespace detail

template<std::size_t N, typename CharT, bool NullTerminated = false, typename Traits = std::char_traits<CharT>>
class basic_static_string : private std::conditional_t<NullTerminated, detail::static_nullterminated_string_base<N, CharT, Traits>, detail::static_string_base<N, CharT, Traits>>
{
  // ...
};

template<std::size_t N>
using static_string = basic_static_string<N, char, false, std::char_traits<char>>;

template<std::size_t N>
using cstring = basic_static_string<N, char, true, std::char_traits<char>>;

}

int main() {
    constexpr auto SIZE = 64;
    static_assert(sizeof(boost::static_string<SIZE>) != SIZE + 1);
    static_assert(sizeof(boost::cstring<SIZE>) == SIZE + 1);
    return 0;
}

The question is: could such new functionallity be in scope of this library? Would you accept PR with such extension?

Unused static_string doc customizations

We recently deleted the following code that had been unused. Do we need to introduce any of the originally intended behavior behind this code? (I'm guessing the second one below can be left out. ๐Ÿฅš)

<!-- CLASS_DETAIL_TEMPLATE BEGIN -->
<xsl:when test="$normal-tparam = 'InputIterator'"><xsl:text>__InputIterator__</xsl:text></xsl:when>
<!-- CLASS_DETAIL_TEMPLATE END -->
<!-- INCLUDES_FOOT_TEMPLATE BEGIN -->
  <xsl:choose>
    <xsl:when test="contains($file, 'supercalifragilisticexpialidocious')">
      <xsl:text>&#xd;&#xd;Easter Egg&#xd;</xsl:text>
    </xsl:when>
  </xsl:choose>
<!-- INCLUDES_FOOT_TEMPLATE END -->

Compilation error when using c++20 without char8_t support

Using the c++20 version of the standard does not automatically support char8_t. Compilers have options to disable various features, including char8_t support (for example, '-fno-char8_t' in GCC). It is more correct to check the support directly for char8_t via __cpp_char8_t.

Warnings when compiling on 32 bits platform

Having some warnings when compiling on 32 bits arm with GCC 7.3

static_string.hpp:6366:54: warning: left shift count >= width of type [-Wshift-count-overflow]
     std::size_t const m = (std::size_t(0xe9846af) << 32) + 0x9b1a615d;
                                                      ^~
static_string.hpp:6367:21: warning: right shift count >= width of type [-Wshift-count-overflow]
     seed ^= seed >> 32;
                     ^~
static_string.hpp:6369:21: warning: right shift count >= width of type [-Wshift-count-overflow]
     seed ^= seed >> 32;
                     ^~

Apparently, this code calculate a hash on 64 bits but std::size_t is only 32 bits on my platform.
A further exploration indicate that this code won't be used in my case but is still be compiled.
So, just noisy misleading warnings.

`string_view` compatibility

static_string is really useful when trying to avoid heap allocations. starting to use it, i came across a few issues when it comes to using it with APIs that use std::string_view

  • one cannot create (or assign) a static_string from a string_view (but one can create it from a std::string)
  • one cannot compare static_string with a string_view (one also cannot compare it to std::string, though)
  • one cannot use static_string in APIs that take string_view. this one is tricky, as it would require an implicit operator string_view, which is probably nothing we want to have. std::string gets around this limitation via a ctor signature of string_view that takes a std::string ... not ideal, but one could potentially add an as_string_view method to avoid adding too much noise

thoughts?

warnings

The following warnings are still disabled as errors in CI:

  • restrict

  • array-bounds

  • stringop-overflow

  • unused-function

  • noexcept-type

Boost CMake testing procedure doesn't work for StaticString

The documented testing procedure

mkdir __build && cd __build
cmake -DBUILD_TESTING=ON -DBOOST_INCLUDE_LIBRARIES=static_string ..
cmake --build . --target tests
ctest --output-on-failure --no-tests=error

fails for Boost.StaticString, because the test executables aren't built by the target tests. BoostTest handles this automatically, but for tests declared manually, one needs to first declare the tests target if not present

if(NOT TARGET tests)
    add_custom_target(tests)
endif()

and then for each test executable, use add_dependencies(test my_test_executable).

Or, since there is already a target boost_static_string_all_tests, it should be enough to make it a dependency of tests: add_dependencies(tests boost_static_string_all_tests).

(For this to keep working after the eventual fix, it might be a good idea to add it to CI.)

It's also good practice to make the test executables EXCLUDE_FOR_ALL, so that building the tests target builds them, but building the default target doesn't, but this step is not in principle required.

Regression in static_string comparison operators (Boost 1.82)

Dear static_string/boost maintainers,

Simple reproduction case for a new compilation error I have since 1.82:

#include <boost/static_string.hpp>
struct My_uuid: public boost::static_string<32> {
};

static inline bool comparison_issue() {
  My_uuid s1, s2;
  return s1 < s2;
}

The error:

~/project/article.cpp:11:13: error: use of overloaded operator '<' is ambiguous (with operand types 'My_uuid' and 'My_uuid')
  return s1 < s2;

~/local/include/boost/static_string/static_string.hpp:5750:1: note: candidate function [with N = 32, CharT = char, Traits = std::char_traits<char>, T = My_uuid, $4 = void]
operator<(

~/local/include/boost/static_string/static_string.hpp:5768:1: note: candidate function [with N = 32, CharT = char, Traits = std::char_traits<char>, T = My_uuid, $4 = void]
operator<(

This code worked from Boost 1.74 up until Boost 1.81 (Code is 3 years old).

Compiler is Clang 14 in Ubuntu 22.04 and Boost is/was always compiled and installed from Source.

PS: Thank you for the library!

rgds, Kira

`constexpr boost::static_strings::basic_static_string s( "name" );` fails

constexpr boost::static_strings::basic_static_string s( "name" ); fails to compile (under C++20): https://godbolt.org/z/fvPs3rxa7

Background: in order to write functions that take strings as template arguments, as in function<"string">(), one needs to declare the template parameter a static string, because neither char const* nor std::string_view work.

To avoid needless reinvention of static strings, ours should (probably) be useful in this role. But it isn't, for at least the reason above.

constexpr constructors

there are a few small problems with using static_string in constexpr.

one cannot create a static_string from a character literal:

constexpr boost::static_string<16> s{"yada"};

one cannot return a static_string from a constexpr function:

constexpr boost::static_string<16> gen()
{
    boost::static_string<16> ret;
    return ret;
}

constexpr auto x = gen();

build string in-place?

I cannot find a way to do this, so I suppose it is a feature request (unless I miss something).

I want to have a static_string allocated, then write some data into it via fmt::format_to_n (or you could imagine snprintf, etc), and then tell it "here is your new length." I am trying to avoid an extra copy.

eg:

static_string<10> str;
auto ret = fmt::format_to_n(
   str.data(),
   str.capacity(),
   "foo {}"
   123);
auto length = ret.out - str.data();
str.set_length_to(length);     // this function does not exist

I cannot use resize() because that will stomp the data with char(), which is 0.

Note: one alternative is to pass an insertion iterator, like so:

fmt::format_to_n(
  std::back_inserter(str),
  ...);

However, this repeatedly calls push_back on the string, which repeatedly null-terminates the data unnecessarily.
Only the final null terminator matters, so the others are wasted work.

Or maybe there is a way to do this already, which I am missing?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.