mirror of
https://github.com/arun11299/cpp-jwt.git
synced 2025-05-15 01:08:31 +00:00
Implement string view (with bot limited functionality)
This commit is contained in:
parent
6a7d2d69c0
commit
063a0af131
6 changed files with 790 additions and 0 deletions
349
include/jwt/string_view.hpp
Normal file
349
include/jwt/string_view.hpp
Normal file
|
@ -0,0 +1,349 @@
|
|||
#ifndef JWT_STRING_VIEW_HPP
|
||||
#define JWT_STRING_VIEW_HPP
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
namespace jwt {
|
||||
|
||||
/*
|
||||
* Implements c++17 string_view.
|
||||
* Could have used boost::string_ref, but wanted to
|
||||
* keep boost dependency off from this library.
|
||||
*/
|
||||
|
||||
template <
|
||||
typename CharT,
|
||||
typename Traits = std::char_traits<CharT>
|
||||
>
|
||||
class basic_string_view
|
||||
{
|
||||
public: // Member Types
|
||||
using traits_type = std::char_traits<CharT>;
|
||||
using value_type = CharT;
|
||||
using pointer = const CharT*;
|
||||
using const_pointer = const CharT*;
|
||||
using reference = const CharT&;
|
||||
using const_reference = const CharT&;
|
||||
using iterator = const CharT*;
|
||||
using const_iterator = const CharT*;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
using size_type = size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
static constexpr size_type npos = size_type(-1);
|
||||
|
||||
public: // 'tors
|
||||
/// The default constructor;
|
||||
basic_string_view() = default;
|
||||
|
||||
/// Construct from string literal
|
||||
basic_string_view(const CharT* str) noexcept
|
||||
: data_(str)
|
||||
, len_(str ? traits_type::length(str) : 0)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct from CharT pointer and provided length
|
||||
basic_string_view(const CharT* p, size_type len) noexcept
|
||||
: data_(p)
|
||||
, len_(len)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct from std::string
|
||||
template <typename Allocator>
|
||||
basic_string_view(
|
||||
const std::basic_string<CharT, Traits, Allocator>& str) noexcept
|
||||
: data_(str.data())
|
||||
, len_(str.length())
|
||||
{
|
||||
}
|
||||
|
||||
/// Copy constructor
|
||||
basic_string_view(const basic_string_view&) = default;
|
||||
|
||||
/// Assignment operator
|
||||
basic_string_view& operator=(const basic_string_view&) = default;
|
||||
|
||||
/// Destructor
|
||||
~basic_string_view()
|
||||
{
|
||||
data_ = nullptr;
|
||||
len_ = 0;
|
||||
}
|
||||
|
||||
public: // Exposed APIs
|
||||
/// Iterator Member Functions
|
||||
|
||||
iterator begin() const noexcept { return data_; }
|
||||
iterator end() const noexcept { return data_ + len_; }
|
||||
|
||||
iterator rbegin() const noexcept { return reverse_iterator(end()); }
|
||||
iterator rend() const noexcept { return reverse_iterator(begin()); }
|
||||
|
||||
const_iterator cbegin() const noexcept { return begin(); }
|
||||
const_iterator cend() const noexcept { return end(); }
|
||||
|
||||
const_iterator crbegin() const noexcept { return rbegin(); }
|
||||
const_iterator crend() const noexcept { return rend(); }
|
||||
|
||||
/// Capacity Member Functions
|
||||
|
||||
size_type length() const noexcept { return len_; }
|
||||
size_type size() const noexcept { return len_; }
|
||||
|
||||
size_type max_size() const noexcept
|
||||
{
|
||||
return (npos - sizeof(size_type) - sizeof(void*))
|
||||
/ sizeof(value_type) / 4;
|
||||
}
|
||||
|
||||
bool empty() const noexcept { return len_ == 0; }
|
||||
|
||||
/// Element Access Member Functions
|
||||
const_reference operator[](size_type idx) const noexcept
|
||||
{
|
||||
return data_[idx];
|
||||
}
|
||||
|
||||
// NOTE: 'at' not supported
|
||||
//CharT at(size_type idx) const;
|
||||
|
||||
const_reference front() const noexcept
|
||||
{
|
||||
return data_[0];
|
||||
}
|
||||
|
||||
const_reference back() const noexcept
|
||||
{
|
||||
return data_[len_ - 1];
|
||||
}
|
||||
|
||||
const_pointer data() const noexcept
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
/// Modifier Member Functions
|
||||
void remove_prefix(size_type n) noexcept
|
||||
{
|
||||
assert (n < len_ && "Data would point out of bounds");
|
||||
data_ += n;
|
||||
len_ -= n;
|
||||
}
|
||||
|
||||
void remove_suffix(size_type n) noexcept
|
||||
{
|
||||
assert (n < len_ && "Suffix length more than data length");
|
||||
len_ -= n;
|
||||
}
|
||||
|
||||
void swap(basic_string_view& other)
|
||||
{
|
||||
std::swap(data_, other.data_);
|
||||
std::swap(len_, other.len_);
|
||||
}
|
||||
|
||||
/// String Operation Member Functions
|
||||
|
||||
template <typename Allocator>
|
||||
explicit operator std::basic_string<CharT, Traits, Allocator>() const
|
||||
{
|
||||
return {data_, len_};
|
||||
}
|
||||
|
||||
template <typename Allocator = std::allocator<CharT>>
|
||||
std::basic_string<CharT, Traits, Allocator>
|
||||
to_string(const Allocator& alloc = Allocator()) const
|
||||
{
|
||||
return {data_, len_, alloc};
|
||||
}
|
||||
|
||||
// NOTE: Does not throw
|
||||
size_type copy(CharT* dest, size_type n, size_type pos = 0) const noexcept
|
||||
{
|
||||
assert (pos < len_ && n < len_);
|
||||
size_type to_copy = std::min(n, len_ - pos);
|
||||
|
||||
for (size_type i = 0; i < to_copy; i++) {
|
||||
dest[i] = data_[i + pos];
|
||||
}
|
||||
|
||||
return to_copy;
|
||||
}
|
||||
|
||||
// NOTE: Does not throw
|
||||
basic_string_view substr(size_type pos, size_type n = npos) const noexcept
|
||||
{
|
||||
assert (pos < len_ && "Start position should be less than length of the view");
|
||||
assert (n == npos ? 1 : (n - pos) < len_ &&
|
||||
"Substring length asked for is more than the view length");
|
||||
|
||||
if (n == npos) n = len_;
|
||||
|
||||
return basic_string_view{data_ + pos, n};
|
||||
}
|
||||
|
||||
/// Comparison Member Functions
|
||||
int compare(const basic_string_view& other) const noexcept
|
||||
{
|
||||
int ret = traits_type::compare(data_, other.data_, std::min(len_, other.len_));
|
||||
if (ret == 0) {
|
||||
ret = compare_length(len_, other.len_);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int compare(size_type pos, size_type n, basic_string_view other) const noexcept
|
||||
{
|
||||
return substr(pos, n).compare(other);
|
||||
}
|
||||
|
||||
int compare(const CharT* str) const noexcept
|
||||
{
|
||||
return compare(basic_string_view{str});
|
||||
}
|
||||
|
||||
int compare(size_type pos, size_type n, const CharT* str) const noexcept
|
||||
{
|
||||
return compare(pos, n, basic_string_view{str});
|
||||
}
|
||||
|
||||
int compare(size_type pos, size_type n1, const CharT* str, size_type n2) const noexcept
|
||||
{
|
||||
return compare(pos, n1, basic_string_view{str, n2});
|
||||
}
|
||||
|
||||
/// Find operations
|
||||
size_type find(const CharT* str, size_type pos, size_type n) const noexcept;
|
||||
|
||||
size_type find(const CharT ch, size_type pos) const noexcept;
|
||||
|
||||
size_type find(basic_string_view sv, size_type pos = 0) const noexcept
|
||||
{
|
||||
return find(sv.data(), pos, sv.length());
|
||||
}
|
||||
|
||||
size_type find(const CharT* str, size_type pos = 0) const noexcept
|
||||
{
|
||||
return find(str, pos, traits_type::length(str));
|
||||
}
|
||||
|
||||
size_type rfind(const CharT* str, size_type pos, size_type n) const noexcept;
|
||||
|
||||
size_type rfind(const CharT ch, size_type pos) const noexcept;
|
||||
|
||||
size_type rfind(basic_string_view sv, size_type pos = 0) const noexcept
|
||||
{
|
||||
return rfind(sv.data(), pos, sv.length());
|
||||
}
|
||||
|
||||
size_type rfind(const CharT* str, size_type pos = 0) const noexcept
|
||||
{
|
||||
return rfind(str, pos, traits_type::length(str));
|
||||
}
|
||||
|
||||
size_type find_first_of(const CharT* str, size_type pos, size_type count) const noexcept;
|
||||
|
||||
size_type find_first_of(basic_string_view str, size_type pos = 0) const noexcept
|
||||
{
|
||||
return find_first_of(str.data(), pos, str.length());
|
||||
}
|
||||
|
||||
size_type find_first_of(CharT ch, size_type pos = 0) const noexcept
|
||||
{
|
||||
return find(ch, pos);
|
||||
}
|
||||
|
||||
size_type find_first_of(const CharT* str, size_type pos = 0) const noexcept
|
||||
{
|
||||
return find_first_of(str, pos, traits_type::length(str));
|
||||
}
|
||||
|
||||
size_type find_last_of(const CharT* str, size_type pos, size_type count) const noexcept;
|
||||
|
||||
size_type find_last_of(basic_string_view str, size_type pos = npos) const noexcept
|
||||
{
|
||||
return find_last_of(str.data(), (pos == npos ? len_ - 1 : pos), str.length());
|
||||
}
|
||||
|
||||
size_type find_last_of(CharT ch, size_type pos = npos) const noexcept
|
||||
{
|
||||
return rfind(ch, pos == npos ? len_ - 1 : pos);
|
||||
}
|
||||
|
||||
size_type find_last_of(const CharT* str, size_type pos = npos) const noexcept
|
||||
{
|
||||
return find_last_of(str, (pos == npos ? len_ - 1 : pos), traits_type::length(str));
|
||||
}
|
||||
|
||||
size_type find_first_not_of(const CharT* str, size_type pos, size_type n) const noexcept;
|
||||
|
||||
size_type find_first_not_of(CharT ch, size_type pos) const noexcept;
|
||||
|
||||
size_type find_first_not_of(basic_string_view str, size_type pos = 0) const noexcept
|
||||
{
|
||||
return find_first_not_of(str.data(), pos, str.length());
|
||||
}
|
||||
|
||||
size_type find_first_not_of(const CharT* str, size_type pos = 0) const noexcept
|
||||
{
|
||||
return find_first_not_of(str, pos, traits_type::length(str));
|
||||
}
|
||||
|
||||
size_type find_last_not_of(const CharT* str, size_type pos, size_type n) const noexcept;
|
||||
|
||||
size_type find_last_not_of(CharT ch, size_type pos) const noexcept;
|
||||
|
||||
size_type find_last_not_of(basic_string_view str, size_type pos = npos) const noexcept
|
||||
{
|
||||
return find_last_not_of(str.data(), (pos == npos ? len_ - 1 : pos), str.length());
|
||||
}
|
||||
|
||||
size_type find_last_not_of(const CharT* str, size_type pos = npos) const noexcept
|
||||
{
|
||||
return find_last_not_of(str, (pos == npos ? len_ - 1 : pos), traits_type::length(str));
|
||||
}
|
||||
|
||||
/// Comparison operators Member Functions
|
||||
/*
|
||||
friend bool operator== (basic_string_view a, basic_string_view b) noexcept;
|
||||
|
||||
friend bool operator!= (basic_string_view a, basic_string_view b) noexcept;
|
||||
|
||||
friend bool operator< (basic_string_view a, basic_string_view b) noexcept;
|
||||
|
||||
friend bool operator> (basic_string_view a, basic_string_view b) noexcept;
|
||||
|
||||
friend bool operator<= (basic_string_view a, basic_string_view b) noexcept;
|
||||
|
||||
friend bool operator>= (basic_string_view a, basic_string_view b) noexcept;
|
||||
*/
|
||||
|
||||
private: // private implementations
|
||||
|
||||
static constexpr int compare_length(size_type n1, size_type n2) noexcept
|
||||
{
|
||||
return static_cast<difference_type>(n1 - n2) > std::numeric_limits<int>::max()
|
||||
? std::numeric_limits<int>::max()
|
||||
: static_cast<difference_type>(n1 - n2) < std::numeric_limits<int>::min()
|
||||
? std::numeric_limits<int>::min()
|
||||
: static_cast<int>(n1 - n2)
|
||||
;
|
||||
}
|
||||
|
||||
private:
|
||||
// This is what view is basically...
|
||||
const char* data_ = nullptr;
|
||||
size_type len_ = 0;
|
||||
};
|
||||
|
||||
|
||||
} // END namespace jwt
|
||||
|
||||
#include "jwt/impl/string_view.ipp"
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue