mirror of
https://github.com/arun11299/cpp-jwt.git
synced 2025-05-14 16:58:34 +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
Binary file not shown.
248
include/jwt/impl/string_view.ipp
Normal file
248
include/jwt/impl/string_view.ipp
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
#ifndef JWT_STRING_VIEW_IPP
|
||||||
|
#define JWT_STRING_VIEW_IPP
|
||||||
|
|
||||||
|
namespace jwt {
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
auto basic_string_view<CharT, Traits>::find(
|
||||||
|
const CharT* str,
|
||||||
|
size_type pos,
|
||||||
|
size_type n) const noexcept -> size_type
|
||||||
|
{
|
||||||
|
assert (str);
|
||||||
|
assert (n < (len_ - pos) && "Comparison size out of bounds");
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
return pos <= len_ ? pos : npos;
|
||||||
|
}
|
||||||
|
if (n <= len_) {
|
||||||
|
for (; pos <= (len_ - n); ++pos) {
|
||||||
|
if (traits_type::eq(data_[pos], str[0]) &&
|
||||||
|
traits_type::compare(data_ + pos + 1, str + 1, n - 1) == 0) {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
auto basic_string_view<CharT, Traits>::rfind(
|
||||||
|
const CharT* str,
|
||||||
|
size_type pos,
|
||||||
|
size_type n) const noexcept -> size_type
|
||||||
|
{
|
||||||
|
assert (str);
|
||||||
|
assert (pos < len_ && "Position out of bounds");
|
||||||
|
|
||||||
|
if (n <= len_) {
|
||||||
|
pos = std::min(len_ - n, pos);
|
||||||
|
do {
|
||||||
|
if (traits_type::eq(data_[pos], str[0]) &&
|
||||||
|
traits_type::compare(data_ + pos + 1, str + 1, n - 1) == 0) {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
} while (pos-- != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
auto basic_string_view<CharT, Traits>::find(
|
||||||
|
const CharT ch,
|
||||||
|
size_type pos) const noexcept -> size_type
|
||||||
|
{
|
||||||
|
if (pos < len_) {
|
||||||
|
for (size_type i = pos; i < len_; ++i) {
|
||||||
|
if (traits_type::eq(data_[i], ch)) return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
auto basic_string_view<CharT, Traits>::rfind(
|
||||||
|
const CharT ch,
|
||||||
|
size_type pos) const noexcept -> size_type
|
||||||
|
{
|
||||||
|
if (pos < len_) {
|
||||||
|
do {
|
||||||
|
if (traits_type::eq(data_[pos], ch)) {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
} while (pos-- != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
auto basic_string_view<CharT, Traits>::find_first_of(
|
||||||
|
const CharT* str,
|
||||||
|
size_type pos,
|
||||||
|
size_type count) const noexcept -> size_type
|
||||||
|
{
|
||||||
|
assert (str);
|
||||||
|
|
||||||
|
for (size_type i = pos; i < len_; ++i) {
|
||||||
|
auto p = traits_type::find(str, count, data_[i]);
|
||||||
|
if (p) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
auto basic_string_view<CharT, Traits>::find_last_of(
|
||||||
|
const CharT* str,
|
||||||
|
size_type pos,
|
||||||
|
size_type count) const noexcept -> size_type
|
||||||
|
{
|
||||||
|
assert (str);
|
||||||
|
assert (pos < len_ && "Position must be within the bounds of the view");
|
||||||
|
size_type siz = len_;
|
||||||
|
|
||||||
|
if (siz && count) {
|
||||||
|
siz = std::min(pos, siz);
|
||||||
|
|
||||||
|
do {
|
||||||
|
auto p = traits_type::find(str, count, data_[siz]);
|
||||||
|
if (p) {
|
||||||
|
return siz;
|
||||||
|
}
|
||||||
|
} while (siz-- != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
auto basic_string_view<CharT, Traits>::find_first_not_of(
|
||||||
|
const CharT* str,
|
||||||
|
size_type pos,
|
||||||
|
size_type n) const noexcept -> size_type
|
||||||
|
{
|
||||||
|
assert (str);
|
||||||
|
assert (pos < len_&& "Position must be within the bounds of the view");
|
||||||
|
|
||||||
|
for (size_type i = pos; i < len_; ++i)
|
||||||
|
{
|
||||||
|
auto p = traits_type::find(str, n, data_[i]);
|
||||||
|
if (not p) return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
auto basic_string_view<CharT, Traits>::find_last_not_of(
|
||||||
|
const CharT* str,
|
||||||
|
size_type pos,
|
||||||
|
size_type n) const noexcept -> size_type
|
||||||
|
{
|
||||||
|
assert (str);
|
||||||
|
assert (pos < len_ && "Position must be within the bounds of the view");
|
||||||
|
|
||||||
|
do {
|
||||||
|
for (size_type i = 0; i < n; ++i) {
|
||||||
|
if (not traits_type::eq(data_[pos], str[i])) return pos;
|
||||||
|
}
|
||||||
|
} while (pos-- != 0);
|
||||||
|
|
||||||
|
return npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
auto basic_string_view<CharT, Traits>::find_first_not_of(
|
||||||
|
CharT ch,
|
||||||
|
size_type pos) const noexcept -> size_type
|
||||||
|
{
|
||||||
|
assert (pos < len_&& "Position must be within the bounds of the view");
|
||||||
|
|
||||||
|
for (size_type i = pos; i < len_; ++i) {
|
||||||
|
if (not traits_type::eq(data_[i], ch)) return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
auto basic_string_view<CharT, Traits>::find_last_not_of(
|
||||||
|
CharT ch,
|
||||||
|
size_type pos) const noexcept -> size_type
|
||||||
|
{
|
||||||
|
assert (pos < len_ && "Position must be within the bounds of the view");
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (not traits_type::eq(data_[pos], ch)) return pos;
|
||||||
|
} while (pos-- != 0);
|
||||||
|
|
||||||
|
return npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comparison Operators
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
bool operator== (basic_string_view<CharT, Traits> a,
|
||||||
|
basic_string_view<CharT, Traits> b) noexcept
|
||||||
|
{
|
||||||
|
if (a.length() != b.length()) return false;
|
||||||
|
using traits_type = typename basic_string_view<CharT, Traits>::traits_type;
|
||||||
|
using size_type = typename basic_string_view<CharT, Traits>::size_type;
|
||||||
|
|
||||||
|
for (size_type i = 0; i < a.length(); ++i) {
|
||||||
|
if (not traits_type::eq(a[i], b[i])) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
bool operator!= (basic_string_view<CharT, Traits> a,
|
||||||
|
basic_string_view<CharT, Traits> b) noexcept
|
||||||
|
{
|
||||||
|
return not ( a == b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
bool operator< (basic_string_view<CharT, Traits> a,
|
||||||
|
basic_string_view<CharT, Traits> b) noexcept
|
||||||
|
{
|
||||||
|
return a.compare(b) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
bool operator> (basic_string_view<CharT, Traits> a,
|
||||||
|
basic_string_view<CharT, Traits> b) noexcept
|
||||||
|
{
|
||||||
|
return a.compare(b) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
bool operator<= (basic_string_view<CharT, Traits> a,
|
||||||
|
basic_string_view<CharT, Traits> b) noexcept
|
||||||
|
{
|
||||||
|
return a.compare(b) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
bool operator>= (basic_string_view<CharT, Traits> a,
|
||||||
|
basic_string_view<CharT, Traits> b) noexcept
|
||||||
|
{
|
||||||
|
return a.compare(b) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CharT, typename Traits>
|
||||||
|
std::ostream& operator<< (std::ostream& os, basic_string_view<CharT, Traits> sv)
|
||||||
|
{
|
||||||
|
os.write(sv.data(), sv.length());
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // END namespace jwt
|
||||||
|
|
||||||
|
#endif
|
24
include/jwt/jwt.hpp
Normal file
24
include/jwt/jwt.hpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef JWT_HPP
|
||||||
|
#define JWT_HPP
|
||||||
|
|
||||||
|
namespace jwt {
|
||||||
|
|
||||||
|
enum class algorithm
|
||||||
|
{
|
||||||
|
NONE = 0,
|
||||||
|
HS256,
|
||||||
|
HS384,
|
||||||
|
HS512,
|
||||||
|
RS256,
|
||||||
|
RS384,
|
||||||
|
RS512,
|
||||||
|
ES256,
|
||||||
|
ES384,
|
||||||
|
ES512,
|
||||||
|
TERM,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // END namespace jwt
|
||||||
|
|
||||||
|
#endif
|
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
|
BIN
include/jwt/test_sv
Executable file
BIN
include/jwt/test_sv
Executable file
Binary file not shown.
169
include/jwt/test_sv.cc
Normal file
169
include/jwt/test_sv.cc
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include <memory>
|
||||||
|
#include "./string_view.hpp"
|
||||||
|
|
||||||
|
using string_view = jwt::basic_string_view<char>;
|
||||||
|
|
||||||
|
void basic_cons()
|
||||||
|
{
|
||||||
|
// Default construction
|
||||||
|
string_view sv{};
|
||||||
|
assert (sv.length() == 0 && "Size must be zero for default constructor");
|
||||||
|
|
||||||
|
// Construction from string literal
|
||||||
|
string_view sv2{"Arun Muralidharan"};
|
||||||
|
assert (sv2.length() == strlen("Arun Muralidharan") && "Lengths must match");
|
||||||
|
|
||||||
|
const char* haystack = "some really big data with infinite objects....";
|
||||||
|
|
||||||
|
// Construct using part of data
|
||||||
|
string_view sv3{haystack, 4};
|
||||||
|
assert (sv3.length() == 4 && "Partial construction is not ok");
|
||||||
|
assert (sv3.to_string() == "some" && "Partial strings are not equal");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void iterator_test()
|
||||||
|
{
|
||||||
|
string_view sv{"Arun Muralidharan"};
|
||||||
|
for (auto c : sv) std::cout << c;
|
||||||
|
std::cout << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void str_operations()
|
||||||
|
{
|
||||||
|
string_view sv{"Arun Muralidharan"};
|
||||||
|
string_view tmp = sv;
|
||||||
|
sv.remove_prefix(5);
|
||||||
|
assert (sv.to_string() == "Muralidharan" && "Remove prefix failed");
|
||||||
|
|
||||||
|
sv = tmp;
|
||||||
|
sv.remove_suffix(strlen("Muralidharan"));
|
||||||
|
assert (sv.to_string() == "Arun " && "Remove suffix failed");
|
||||||
|
|
||||||
|
sv=tmp;
|
||||||
|
{
|
||||||
|
std::unique_ptr<char[]> dst{new char[32]};
|
||||||
|
sv.copy(dst.get(), 6, 0);
|
||||||
|
dst[6] = '\0';
|
||||||
|
assert (strlen(dst.get()) == 6 && "Copy Failed-1");
|
||||||
|
assert (std::string{dst.get()} == "Arun M" && "Copy Failed-2");
|
||||||
|
|
||||||
|
sv.copy(dst.get(), 8, 4);
|
||||||
|
dst[8] = '\0';
|
||||||
|
assert (strlen(dst.get()) == 8 && "Middle copy failed-1");
|
||||||
|
assert (std::string{dst.get()} == " Muralid" && "Middle copy failed-2");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto ss1 = sv.substr(0, 4);
|
||||||
|
assert (ss1.to_string() == "Arun" && "Substr failed - 1");
|
||||||
|
|
||||||
|
auto ss2 = sv.substr(1, 3);
|
||||||
|
assert (ss2.to_string() == "run" && "Substr failed - 2");
|
||||||
|
|
||||||
|
auto ss3 = sv.substr(0);
|
||||||
|
assert (ss3.length() == sv.length() && "Substr failed - 3");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void find_oper()
|
||||||
|
{
|
||||||
|
string_view sv{"Arun Muralidharan"};
|
||||||
|
auto pos = sv.find("Arun", 0, 4);
|
||||||
|
assert (pos == 0 && "Arun not found in sv");
|
||||||
|
|
||||||
|
pos = sv.find("arun", 0, 4);
|
||||||
|
assert (pos == string_view::npos && "arun is not there in sv");
|
||||||
|
|
||||||
|
sv = "This has a, in it.";
|
||||||
|
pos = sv.find_first_of(",", 0, 1);
|
||||||
|
assert (pos != string_view::npos);
|
||||||
|
assert (pos == 10 && "Comma not found at correct place");
|
||||||
|
|
||||||
|
pos = sv.find_first_of(",", 10, 1);
|
||||||
|
assert (pos != string_view::npos);
|
||||||
|
assert (pos == 10 && "Comma not found at correct place");
|
||||||
|
|
||||||
|
pos = sv.find_first_of(":", 10, 1);
|
||||||
|
assert (pos == string_view::npos);
|
||||||
|
|
||||||
|
pos = sv.find_last_of(",", 5, 1);
|
||||||
|
assert (pos == string_view::npos);
|
||||||
|
|
||||||
|
pos = sv.find_last_of(",", sv.length() - 1, 1);
|
||||||
|
assert (pos != string_view::npos);
|
||||||
|
assert (pos == 10 && "Comma not found at correct place");
|
||||||
|
|
||||||
|
pos = sv.find_first_of(".", 0, 1);
|
||||||
|
assert (pos == sv.length() - 1 && "Dot not found at correct place");
|
||||||
|
|
||||||
|
pos = sv.find_last_of(".", sv.length() - 2, 1);
|
||||||
|
assert (pos == string_view::npos);
|
||||||
|
|
||||||
|
pos = sv.find_last_of(".", sv.length() - 1, 1);
|
||||||
|
assert (pos == sv.length() - 1);
|
||||||
|
|
||||||
|
sv = "Some string :<> with some ??? pattern --**";
|
||||||
|
|
||||||
|
pos = sv.rfind("???", sv.length() - 1, 3);
|
||||||
|
assert (pos != string_view::npos && "??? not found");
|
||||||
|
assert (pos == 26 && "??? not found at the correct place");
|
||||||
|
|
||||||
|
sv = "ATCGTTCACGRRRTCGGGGACGTC";
|
||||||
|
|
||||||
|
pos = sv.find_first_not_of("ATCG");
|
||||||
|
assert (pos != string_view::npos);
|
||||||
|
assert (pos == 10);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void conversions()
|
||||||
|
{
|
||||||
|
auto c2sv = [](int num) -> string_view {
|
||||||
|
switch (num) {
|
||||||
|
case 1: return "one";
|
||||||
|
case 2: return "two";
|
||||||
|
case 3: return "three";
|
||||||
|
default: return "many";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
auto res = c2sv(2);
|
||||||
|
assert (res.to_string() == "two");
|
||||||
|
|
||||||
|
auto s2sv = [](std::string s) {
|
||||||
|
return s;
|
||||||
|
};
|
||||||
|
|
||||||
|
s2sv(static_cast<std::string>(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
void comparisons()
|
||||||
|
{
|
||||||
|
string_view s1{"Apple"};
|
||||||
|
string_view s2{"Orange"};
|
||||||
|
|
||||||
|
assert (s1 != s2 && "Two string views are not equal");
|
||||||
|
assert (s2 > s1 && "Orange is lexicographically bigger than Apple");
|
||||||
|
|
||||||
|
s2 = "Apples";
|
||||||
|
assert (s2 > s1 && "Because Apples is plural");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
basic_cons();
|
||||||
|
iterator_test();
|
||||||
|
str_operations();
|
||||||
|
find_oper();
|
||||||
|
conversions();
|
||||||
|
comparisons();
|
||||||
|
return 0;
|
||||||
|
};
|
Loading…
Add table
Add a link
Reference in a new issue