Skip to content

string_view lite - A C++17-like string_view for C++98, C++11 and later in a single-file header-only library

License

Notifications You must be signed in to change notification settings

martinmoene/string-view-lite

Folders and files

NameName
Last commit message
Last commit date

Latest commit

a47222b · Jun 8, 2024
Jan 14, 2024
Nov 28, 2022
Oct 15, 2022
Jun 8, 2024
Dec 3, 2022
May 31, 2019
Feb 5, 2022
Jun 28, 2020
Dec 23, 2017
Jun 20, 2020
Jun 28, 2020
Jun 8, 2024
Jun 5, 2018
Jun 1, 2024
Oct 5, 2020
Jun 8, 2024

Repository files navigation

string_view lite: A single-file header-only version of a C++17-like string_view for C++98, C++11 and later

Language License Build Status Build status Version download Conan Vcpkg Try it on wandbox Try it on godbolt online

Contents

Example usage

#include "nonstd/string_view.hpp"
#include <iostream>

using namespace std::literals;
using namespace nonstd::literals;
using namespace nonstd;

void write( string_view sv )
{
    std::cout << sv;
}

int main()
{
    write( "hello"     );   // C-string
    write( ", "s       );   // std::string
    write( "world!"_sv );   // nonstd::string_view
}

Compile and run

prompt> g++ -Wall -std=c++14 -I../include/ -o 01-basic.exe 01-basic.cpp && 01-basic.exe
hello, world!

In a nutshell

string-view lite is a single-file header-only library to provide a non-owning reference to a string. The library provides a C++17-like string_view for use with C++98 and later. If available, std::string_view is used, unless configured otherwise.

Features and properties of string-view lite are ease of installation (single header), freedom of dependencies other than the standard library. To mimic C++17-like cooperation with std::string, nonstd::string_view provides several non-standard conversion functions. These functions may be omitted via configuration.

License

string-view lite is distributed under the Boost Software License.

Dependencies

string-view lite has no other dependencies than the C++ standard library.

Installation

string-view lite is a single-file header-only library. Put string_view.hpp in the include folder directly into the project source tree or somewhere reachable from your project.

Or, if you use the conan package manager, follow these steps:

  1. Add nonstd-lite to the conan remotes:

     conan remote add nonstd-lite https://api.bintray.com/conan/martinmoene/nonstd-lite
    
  2. Add a reference to string-view-lite to the requires section of your project's conanfile.txt file:

     [requires]
     string-view-lite/[~=1]@nonstd-lite/testing
    
  3. Run conan's install command:

     conan install
    

Synopsis

Contents
Documentation of std::string_view
C++20 extensions
Non-standard extensions
Configuration

Documentation of std::string_view

Depending on the compiler and C++-standard used, nonstd::string_view behaves less or more like std::string_view. To get an idea of the capabilities of nonstd::string_view with your configuration, look at the output of the tests, issuing string-view-lite.t --pass @. For std::string_view, see its documentation at cppreference.

C++20 extensions

string_view-lite provides the following C++20 extensions.

  • [[nodiscard]] constexpr bool empty() const noexcept;
  • constexpr bool starts_with( basic_string_view v ) const noexcept; // (1)
  • constexpr bool starts_with( CharT c ) const noexcept; // (2)
  • constexpr bool starts_with( CharT const * s ) const; // (3)
  • constexpr bool ends_with( basic_string_view v ) const noexcept; // (1)
  • constexpr bool ends_with( CharT c ) const noexcept; // (2)
  • constexpr bool ends_with( CharT const * s ) const; // (3)

Note: [[nodiscard]], constexpr and noexcept if available.

Non-standard extensions

string_view literals sv and _sv

clang compilers do not allow to write auto sv = "..."sv with string-view lite under C++11. To still provide a literal operator that can be used in that case, string-view lite also provides _sv. See section Configuration for how to control the presence of these operators.

The literal operators are declared in the namespace nonstd::literals::string_view_literals, where both literals and string_view_literals are inline namespaces, if supported. Access to these operators can be gained with using namespace nonstd::literals, using namespace nonstd::string_view_literals, and using namespace nonstd::literals::string_view_literals. If inline namespaces are not supported by the compiler, only the latter form is available.

Cooperation between std::string and nonstd::string_view

string-view lite can provide several methods and free functions to mimic the cooperation between std::string and nonstd::string_view that exists in C++17. See the table below. Several macros allow you to control the presence of these functions, see section Configuration.

Kind Std Function or method
Free functions   macro nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
std::string_view    
to_string() >=C++17 template< class CharT, class Traits, class Allocator=std::allocator<CharT> >
std::basic_string<CharT, Traits, Allocator>
to_string( std::basic_string_view<CharT, Traits> v, Allocator const & a=Allocator() );
to_string_view() >=C++17 template< class CharT, class Traits, class Allocator >
std::basic_string_view<CharT, Traits>
to_string_view( std::basic_string<CharT, Traits, Allocator> const & s );
nonstd::string_view    
to_string()
 
non-msvc14 (vs2015)
>=C++11 template< class CharT, class Traits, class Allocator = std::allocator<CharT> >
std::basic_string<CharT, Traits, Allocator>
to_string( basic_string_view<CharT, Traits> v, Allocator const & a = Allocator() );
to_string()
 
msvc14 (vs2015)
<C++11 template< class CharT, class Traits >
std::basic_string<CharT, Traits>
to_string( basic_string_view<CharT, Traits> v );
to_string()
 
msvc14 (vs2015)
<C++11 template< class CharT, class Traits, class Allocator >
std::basic_string<CharT, Traits, Allocator>
to_string( basic_string_view<CharT, Traits> v, Allocator const & a );
to_string_view() >=C++98 template< class CharT, class Traits, class Allocator >
basic_string_view<CharT, Traits>
to_string_view( std::basic_string<CharT, Traits, Allocator> const & s );
     
Class methods   macro nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
nonstd::basic_string_view    
Constructor >=C++98 template< class Allocator >
basic_string_view( std::basic_string<CharT, Traits, Allocator> const & s ) nssv_noexcept;
Converting operator >=C++11 template< class Allocator >
explicit operator std::basic_string<CharT, Traits, Allocator>() const;
to_string() >=C++11 template< class Allocator = std::allocator<CharT> >
std::basic_string<CharT, Traits, Allocator>
to_string( Allocator const & a = Allocator() ) const;
to_string() <C++11 std::basic_string<CharT, Traits>
to_string() const;
to_string() <C++11 template< class Allocator >
std::basic_string<CharT, Traits, Allocator>
to_string( Allocator const & a ) const;
     
Literal operator sv >=C++11 macro nssv_CONFIG_STD_SV_OPERATOR
    constexpr string_view operator "" sv( const char* str, size_t len ) noexcept;
    constexpr u16string_view operator "" sv( const char16_t* str, size_t len ) noexcept;
    constexpr u32string_view operator "" sv( const char32_t* str, size_t len ) noexcept;
    constexpr wstring_view operator "" sv( const wchar_t* str, size_t len ) noexcept;
     
Literal operator _sv >=C++11 macro nssv_CONFIG_USR_SV_OPERATOR
    constexpr string_view operator "" _sv( const char* str, size_t len ) noexcept;
    constexpr u16string_view operator "" _sv( const char16_t* str, size_t len ) noexcept;
    constexpr u32string_view operator "" _sv( const char32_t* str, size_t len ) noexcept;
    constexpr wstring_view operator "" _sv( const wchar_t* str, size_t len ) noexcept;

Configuration

Tweak header

If the compiler supports __has_include(), string-view lite supports the tweak header mechanism. Provide your tweak header as nonstd/string_view.tweak.hpp in a folder in the include-search-path. In the tweak header, provide definitions as documented below, like #define nssv_CONFIG_NO_EXCEPTIONS 1.

Standard selection macro

-Dnssv_CPLUSPLUS=199711L
Define this macro to override the auto-detection of the supported C++ standard, if your compiler does not set the __cpluplus macro correctly.

Select std::string_view or nonstd::string_view

At default, string-view lite uses std::string_view if it is available and lets you use it via namespace nonstd. You can however override this default and explicitly request to use std::string_view as nonstd::string_view or use string-view lite's nonstd::string_view via the following macros.

-Dnssv_CONFIG_SELECT_STRING_VIEW=nssv_STRING_VIEW_DEFAULT
Define this to nssv_STRING_VIEW_STD to select std::string_view as nonstd::string_view. Define this to nssv_STRING_VIEW_NONSTD to select nonstd::string_view as nonstd::string_view. Default is undefined, which has the same effect as defining to nssv_STRING_VIEW_DEFAULT.

Note: nssv_CONFIG_SELECT_STD_STRING_VIEW and nssv_CONFIG_SELECT_NONSTD_STRING_VIEW are deprecated and have been removed.

Disable exceptions

-Dnssv_CONFIG_NO_EXCEPTIONS=0 Define this to 1 if you want to compile without exceptions. If not defined, the header tries and detect if exceptions have been disabled (e.g. via -fno-exceptions). Default is undefined.

Add or omit literal operators sv and _sv

-Dnssv_CONFIG_STD_SV_OPERATOR=1
Define this to 1 to provide literal operator sv to create a string_view from a literal string. Default is 0. Note that literal operators without leading underscore are reserved for the C++ standard.

-Dnssv_CONFIG_USR_SV_OPERATOR=0
Define this to 0 to omit literal operator _sv to create a string_view from a literal string. Default is 1.

Omit cooperation between std::stringnonstd::string_view

At default, string-view lite provides several methods and free functions to mimic the cooperation between std::string and nonstd::string_view (or std::string_view) that exists in C++17. See section Non-standard extensions. The following macros allow you to control the presence of these functions.

-Dnssv_CONFIG_CONVERSION_STD_STRING=1
Define this to 1 to provide std::stringnonstd::string_view interoperability via methods of nonstd::basic_string_view and free functions, define it to 0 to omit all said methods and functions. Default is undefined.

-Dnssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS=1
Define this to 1 to provide std::stringnonstd::string_view interoperability via methods of nonstd::basic_string_view, define it to 0 to omit all said methods. Default is undefined.

-Dnssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS=1
Define this to 1 to provide std::stringnonstd::string_view interoperability via free functions, define it to 0 to omit all said functions. This also controls the presence of these function if std::string_view is used. Default is undefined.

Omit use of streams

At default, string-view lite provides operations to overload the operator<<. If you want to use the library without the use of standard streams, you can control this with the following macro:

-Dnssv_CONFIG_NO_STREAM_INSERTION=1
Define this to 1 to omit the use of standard streams. Default is undefined.

Avoid constexpr with std::search()

At default, string-view lite may use constexpr with std::search() for string_view::find() when compiling for C++11 or C++14, whereas std::search() is only constexpr since C++20. This may occur when macro __OPTIMIZE__ is not defined and a non-recursive implementation for search is selected. Macro __OPTIMIZE__ is used with GCC and clang.

If you encounter an error related to this, you can control this behaviour with the following macro:

-Dnssv_CONFIG_CONSTEXPR11_STD_SEARCH=0
Define this to 0 to omit the use constexpr with std::search() and substitute a local implementation using nssv_constexpr14. Default is 1.

Enable compilation errors

-Dnssv_CONFIG_CONFIRMS_COMPILATION_ERRORS=0
Define this macro to 1 to experience the by-design compile-time errors of the library in the test suite. Default is 0.

Reported to work with

The table below mentions the compiler versions string-view lite is reported to work with.

OS Compiler Versions
Windows Clang/LLVM ?
  GCC 7.2.0
  Visual C++
(Visual Studio)
8 (2005), 9 (2008), 10 (2010), 11 (2012),
12 (2013), 14 (2015), 15 (2017)
GNU/Linux Clang/LLVM 3.5 - 6.0
  GCC 4.8 - 8
OS X Clang/LLVM Xcode 6, Xcode 7, Xcode 8, Xcode 9

Building the tests

To build the tests you need:

The lest test framework is included in the test folder.

The following steps assume that the string-view lite source code has been cloned into a directory named c:\string-view-lite.

  1. Create a directory for the build outputs for a particular architecture. Here we use c:\string-view-lite\build-win-x86-vc10.

     cd c:\string-view-lite
     md build-win-x86-vc10
     cd build-win-x86-vc10
    
  2. Configure CMake to use the compiler of your choice (run cmake --help for a list).

     cmake -G "Visual Studio 10 2010" -DSTRING_VIEW_LITE_OPT_BUILD_TESTS=ON ..
    
  3. Build the test suite in the Debug configuration (alternatively use Release).

     cmake --build . --config Debug
    
  4. Run the test suite.

     ctest -V -C Debug
    

All tests should pass, indicating your platform is supported and you are ready to use string-view lite.

Other implementations of string_view

Notes and references

Interface and specification

Presentations

Proposals

Appendix

A.1 Compile-time information

The version of string-view lite is available via tag [.version]. The following tags are available for information on the compiler and on the C++ standard library used: [.compiler], [.builtins], [.stdc++], [.stdlanguage] and [.stdlibrary].

A.2 string-view lite test specification

click to expand

string_view: Allows to default construct an empty string_view
string_view: Allows to construct from pointer and size
string_view: Allows to construct from C-string
string_view: Allows to copy-construct from empty string_view
string_view: Allows to copy-construct from non-empty string_view
string_view: Disallows to copy-construct from nullptr (C++11)
string_view: Disallows to copy-assign from nullptr (C++11)
string_view: Allows to copy-assign from empty string_view
string_view: Allows to copy-assign from non-empty string_view
string_view: Allows forward iteration
string_view: Allows const forward iteration
string_view: Allows reverse iteration
string_view: Allows const reverse iteration
string_view: Allows to obtain the size of the view via size()
string_view: Allows to obtain the size of the view via length()
string_view: Allows to obtain the maximum size a view can be via max_size()
string_view: Allows to check for an empty string_view via empty()
string_view: Allows to observe an element via array indexing
string_view: Allows to observe an element via at()
string_view: Throws at observing an element via at() with an index of size() or larger
string_view: Allows to observe elements via data()
string_view: Yields nullptr (or NULL) with data() for an empty string_view
string_view: Allows to remove a prefix of n elements
string_view: Allows to remove a suffix of n elements
string_view: Allows to swap with other string_view
string_view: Allows to copy a substring of length n, starting at position pos (default: 0) via copy()
string_view: Throws if requested position of copy() exceeds string_view's size()
string_view: Allow to obtain a sub string, starting at position pos (default: 0) and of length n (default full), via substr()
string_view: Throws if requested position of substr() exceeds string_view's size()
string_view: Allows to lexically compare to another string_view via compare(), (1)
string_view: Allows to compare empty string_views as equal via compare(), (1)
string_view: Allows to constexpr-compare string_views via compare(), (1) (C++14)
string_view: Allows to compare a sub string to another string_view via compare(), (2)
string_view: Allows to compare a sub string to another string_view sub string via compare(), (3)
string_view: Allows to compare to a C-string via compare(), (4)
string_view: Allows to compare a sub string to a C-string via compare(), (5)
string_view: Allows to compare a sub string to a C-string prefix via compare(), (6)
string_view: Allows to check for a prefix string_view via starts_with(), (1)
string_view: Allows to check for a prefix character via starts_with(), (2)
string_view: Allows to check for a prefix C-string via starts_with(), (3)
string_view: Allows to check for a suffix string_view via ends_with(), (1)
string_view: Allows to check for a suffix character via ends_with(), (2)
string_view: Allows to check for a suffix C-string via ends_with(), (3)
string_view: Allows to search for a string_view substring, starting at position pos (default: 0) via find(), (1)
string_view: Allows to search for a character, starting at position pos (default: 0) via find(), (2)
string_view: Allows to search for a C-string substring, starting at position pos and of length n via find(), (3)
string_view: Allows to search for a C-string substring, starting at position pos (default: 0) via find(), (4)
string_view: Allows to search backwards for a string_view substring, starting at position pos (default: npos) via rfind(), (1)
string_view: Allows to search backwards for a character, starting at position pos (default: npos) via rfind(), (2)
string_view: Allows to search backwards for a C-string substring, starting at position pos and of length n via rfind(), (3)
string_view: Allows to search backwards for a C-string substring, starting at position pos (default: 0) via rfind(), (4)
string_view: Allows to search for the first occurrence of any of the characters specified in a string view, starting at position pos (default: 0) via find_first_of(), (1)
string_view: Allows to search for a character, starting at position pos (default: 0) via find_first_of(), (2)
string_view: Allows to search for the first occurrence of any of the characters specified in a C-string, starting at position pos and of length n via find_first_of(), (3)
string_view: Allows to search for the first occurrence of any of the characters specified in a C-string, starting at position pos via find_first_of(), (4)
string_view: Allows to search backwards for the last occurrence of any of the characters specified in a string view, starting at position pos (default: npos) via find_last_of(), (1)
string_view: Allows to search backwards for a character, starting at position pos (default: 0) via find_last_of(), (2)
string_view: Allows to search backwards for the first occurrence of any of the characters specified in a C-string, starting at position pos and of length n via find_last_of(), (3)
string_view: Allows to search backwards for the first occurrence of any of the characters specified in a C-string, starting at position pos via find_last_of(), (4)
string_view: Allows to search for the first character not specified in a string view, starting at position pos (default: 0) via find_first_not_of(), (1)
string_view: Allows to search for the first character not equal to the specified character, starting at position pos (default: 0) via find_first_not_of(), (2)
string_view: Allows to search for  the first character not equal to any of the characters specified in a C-string, starting at position pos and of length n via find_first_not_of(), (3)
string_view: Allows to search for  the first character not equal to any of the characters specified in a C-string, starting at position pos via find_first_not_of(), (4)
string_view: Allows to search backwards for the first character not specified in a string view, starting at position pos (default: npos) via find_last_not_of(), (1)
string_view: Allows to search backwards for the first character not equal to the specified character, starting at position pos (default: npos) via find_last_not_of(), (2)
string_view: Allows to search backwards for  the first character not equal to any of the characters specified in a C-string, starting at position pos and of length n via find_last_not_of(), (3)
string_view: Allows to search backwards for  the first character not equal to any of the characters specified in a C-string, starting at position pos via find_last_not_of(), (4)
string_view: Allows to create a string_view, wstring_view, u16string_view, u32string_view via literal "sv"
string_view: Allows to create a string_view via literal "sv", using namespace nonstd::literals::string_view_literals
string_view: Allows to create a string_view via literal "sv", using namespace nonstd::string_view_literals
string_view: Allows to create a string_view via literal "sv", using namespace nonstd::literals
string_view: Allows to create a string_view, wstring_view, u16string_view, u32string_view via literal "_sv"
string_view: Allows to create a string_view via literal "_sv", using namespace nonstd::literals::string_view_literals
string_view: Allows to create a string_view via literal "_sv", using namespace nonstd::string_view_literals
string_view: Allows to create a string_view via literal "_sv", using namespace nonstd::literals
string_view: Allows to compare a string_view with another string_view via comparison operators
string_view: Allows to compare a string_view with an object with implicit conversion to string_view via comparison operators
string_view: Allows to compare empty string_view-s as equal via compare() and via operator==()
operator<<: Allows printing a string_view to an output stream
std::hash<>: Hash value of string_view equals hash value of corresponding string object
std::hash<>: Hash value of wstring_view equals hash value of corresponding string object
std::hash<>: Hash value of u16string_view equals hash value of corresponding string object
std::hash<>: Hash value of u32string_view equals hash value of corresponding string object
string_view: construct from std::string [extension]
string_view: convert to std::string via explicit operator [extension]
string_view: convert to std::string via to_string() [extension]
to_string(): convert to std::string via to_string() [extension]
to_string_view(): convert from std::string via to_string_view() [extension]
tweak header: reads tweak header if supported [tweak]