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

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]