Skip to content

Instantly share code, notes, and snippets.

@bindreams
Last active March 30, 2024 12:08
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bindreams/ac9adcf8a2b37ac05ff7047f8728b3c7 to your computer and use it in GitHub Desktop.
Save bindreams/ac9adcf8a2b37ac05ff7047f8728b3c7 to your computer and use it in GitHub Desktop.
string_view compatible std::istringstream.
/**
* MIT No Attribution
*
* Copyright 2020-2024 Anna Zhukova
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify,
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef GIST_GITHUB_COM_ANDREASXP_SVSTREAM_HPP
#define GIST_GITHUB_COM_ANDREASXP_SVSTREAM_HPP
#include <istream>
#include <streambuf>
#include <string_view>
/**
* string_view-compatible buffer for reading read-only characters from memory.
* Implements a buffer based on stackoverflow discussions. Written to be used
* via isviewstream.
*
* @warning sviewbuf does not own memory. If the lifetime of the string ends
* before this buffer, reading from it invokes undefined behavior.
*
* @see https://stackoverflow.com/a/13059195
* @see https://stackoverflow.com/a/46069245
*/
class sviewbuf : public std::streambuf {
private:
using ios_base = std::ios_base;
protected:
pos_type seekoff(
off_type off,
ios_base::seekdir dir,
[[maybe_unused]] ios_base::openmode which = ios_base::in | ios_base::out
) override {
if (dir == ios_base::cur)
gbump(off);
else if (dir == ios_base::end)
setg(eback(), egptr() + off, egptr());
else if (dir == ios_base::beg)
setg(eback(), eback() + off, egptr());
return gptr() - eback();
}
pos_type seekpos(pos_type sp, ios_base::openmode which) override {
return seekoff(sp - pos_type(off_type(0)), ios_base::beg, which);
}
public:
sviewbuf(const char* s, std::size_t count) {
auto p = const_cast<char*>(s);
this->setg(p, p, p + count);
}
sviewbuf(std::string_view str) : sviewbuf(str.data(), str.size()) {}
};
/**
* A std::stringstream analog for string_view.
* Implements a string_view-based input stream based on stackoverflow
* discussions.
*
* @warning isviewstream does not own memory. If the lifetime of the string
* ends before this stream, reading from it invokes undefined behavior.
*
* @see https://stackoverflow.com/a/13059195
* @see https://stackoverflow.com/a/46069245
*/
class isviewstream : private virtual sviewbuf, public std::istream {
public:
isviewstream(std::string_view str) : sviewbuf(str), std::istream(static_cast<std::streambuf*>(this)) {}
};
#endif // GIST_GITHUB_COM_ANDREASXP_SVSTREAM_HPP
@KOLANICH
Copy link

What's the license of this?

@bindreams
Copy link
Author

Thanks for reaching out!
I've updated the code to include the MIT-0 license text.

@KOLANICH
Copy link

Thanks.

@peter-urban
Copy link

Thanks for the gist, helped me to improve the performance of some functions that made use of istringstream.
Just one question: I get a warning about 'unused parameter' which in seekoff, is it safe to just ignore it (using [[maybe_unused]])?

@bindreams
Copy link
Author

Thanks for pointing that out! I updated the gist with your suggestion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment