mirror of
https://github.com/matrix-construct/construct
synced 2024-11-29 10:12:39 +01:00
ircd: Split up string_view.h.
This commit is contained in:
parent
c16a6e8baa
commit
832529396c
5 changed files with 368 additions and 138 deletions
129
include/ircd/array_view.h
Normal file
129
include/ircd/array_view.h
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* charybdis: 21st Century IRC++d
|
||||
* util.h: Miscellaneous utilities
|
||||
*
|
||||
* Copyright (C) 2016 Charybdis Development Team
|
||||
* Copyright (C) 2016 Jason Volk <jason@zemos.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_ARRAY_VIEW_H
|
||||
|
||||
namespace ircd
|
||||
{
|
||||
template<class T> struct array_view;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
struct ircd::array_view
|
||||
{
|
||||
using value_type = const T;
|
||||
using pointer = value_type *;
|
||||
using reference = value_type &;
|
||||
using difference_type = size_t;
|
||||
using iterator = value_type *;
|
||||
using const_iterator = const value_type *;
|
||||
|
||||
value_type *_data { nullptr };
|
||||
value_type *_stop { nullptr };
|
||||
|
||||
public:
|
||||
const value_type *data() const { return _data; }
|
||||
value_type *data() { return _data; }
|
||||
|
||||
size_t size() const { return std::distance(_data, _stop); }
|
||||
bool empty() const { return !size(); }
|
||||
|
||||
const_iterator begin() const { return data(); }
|
||||
const_iterator end() const { return _stop; }
|
||||
const_iterator cbegin() { return data(); }
|
||||
const_iterator cend() { return _stop; }
|
||||
iterator begin() { return data(); }
|
||||
iterator end() { return _stop; }
|
||||
|
||||
const value_type &operator[](const size_t &pos) const
|
||||
{
|
||||
return *(data() + pos);
|
||||
}
|
||||
|
||||
value_type &operator[](const size_t &pos)
|
||||
{
|
||||
return *(data() + pos);
|
||||
}
|
||||
|
||||
const value_type &at(const size_t &pos) const
|
||||
{
|
||||
if(unlikely(pos >= size()))
|
||||
throw std::out_of_range("array_view::range_check");
|
||||
|
||||
return operator[](pos);
|
||||
}
|
||||
|
||||
value_type &at(const size_t &pos)
|
||||
{
|
||||
if(unlikely(pos >= size()))
|
||||
throw std::out_of_range("array_view::range_check");
|
||||
|
||||
return operator[](pos);
|
||||
}
|
||||
|
||||
array_view(value_type *const &start, value_type *const &stop)
|
||||
:_data{start}
|
||||
,_stop{stop}
|
||||
{}
|
||||
|
||||
array_view(value_type *const &start, const size_t &size)
|
||||
:array_view(start, start + size)
|
||||
{}
|
||||
|
||||
array_view(const std::initializer_list<value_type> &list)
|
||||
:array_view(std::begin(list), std::end(list))
|
||||
{}
|
||||
|
||||
template<class U,
|
||||
class A>
|
||||
array_view(const std::vector<U, A> &v)
|
||||
:array_view(v.data(), v.size())
|
||||
{}
|
||||
|
||||
template<class U,
|
||||
class A>
|
||||
array_view(std::vector<U, A> &v)
|
||||
:array_view(v.data(), v.size())
|
||||
{}
|
||||
|
||||
template<size_t SIZE>
|
||||
array_view(value_type (&buffer)[SIZE])
|
||||
:array_view(buffer, SIZE)
|
||||
{}
|
||||
|
||||
template<class U,
|
||||
size_t SIZE>
|
||||
array_view(const std::array<U, SIZE> &array)
|
||||
:array_view(array.data(), array.size())
|
||||
{}
|
||||
|
||||
template<size_t SIZE>
|
||||
array_view(std::array<value_type, SIZE> &array)
|
||||
:array_view(array.data(), array.size())
|
||||
{}
|
||||
|
||||
array_view() = default;
|
||||
};
|
81
include/ircd/byte_view.h
Normal file
81
include/ircd/byte_view.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* charybdis: 21st Century IRC++d
|
||||
* util.h: Miscellaneous utilities
|
||||
*
|
||||
* Copyright (C) 2016 Charybdis Development Team
|
||||
* Copyright (C) 2016 Jason Volk <jason@zemos.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_BYTE_VIEW_H
|
||||
|
||||
namespace ircd
|
||||
{
|
||||
template<class T = string_view> struct byte_view;
|
||||
template<> struct byte_view<string_view>;
|
||||
}
|
||||
|
||||
/// string_view -> bytes
|
||||
template<class T>
|
||||
struct ircd::byte_view
|
||||
{
|
||||
string_view s;
|
||||
|
||||
operator const T &() const
|
||||
{
|
||||
if(unlikely(sizeof(T) > s.size()))
|
||||
throw std::bad_cast();
|
||||
|
||||
return *reinterpret_cast<const T *>(s.data());
|
||||
}
|
||||
|
||||
byte_view(const string_view &s = {})
|
||||
:s{s}
|
||||
{
|
||||
if(unlikely(sizeof(T) > s.size()))
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
||||
// bytes -> bytes (completeness)
|
||||
byte_view(const T &t)
|
||||
:s{byte_view<string_view>{t}}
|
||||
{}
|
||||
};
|
||||
|
||||
/// bytes -> string_view. A byte_view<string_view> is raw data of byte_view<T>.
|
||||
///
|
||||
/// This is an important specialization to take note of. When you see
|
||||
/// byte_view<string_view> know that another type's bytes are being represented
|
||||
/// by the string_view if that type is not string_view family itself.
|
||||
template<>
|
||||
struct ircd::byte_view<ircd::string_view>
|
||||
:string_view
|
||||
{
|
||||
template<class T,
|
||||
typename std::enable_if<!std::is_base_of<std::string_view, T>::value, int *>::type = nullptr>
|
||||
byte_view(const T &t)
|
||||
:string_view{reinterpret_cast<const char *>(&t), sizeof(T)}
|
||||
{}
|
||||
|
||||
/// string_view -> string_view (completeness)
|
||||
byte_view(const string_view &t)
|
||||
:string_view{t}
|
||||
{}
|
||||
};
|
|
@ -184,6 +184,9 @@ namespace ircd
|
|||
#include "util.h"
|
||||
#include "exception.h"
|
||||
#include "string_view.h"
|
||||
#include "vector_view.h"
|
||||
#include "array_view.h"
|
||||
#include "byte_view.h"
|
||||
#include "allocator.h"
|
||||
#include "buffer.h"
|
||||
#include "date.h"
|
||||
|
|
|
@ -30,13 +30,9 @@ namespace ircd
|
|||
{
|
||||
struct string_view;
|
||||
|
||||
template<class T> struct vector_view;
|
||||
|
||||
template<class T = string_view> struct byte_view;
|
||||
template<> struct byte_view<string_view>;
|
||||
|
||||
template<int (&test)(int) = std::isprint> auto ctype(const string_view &s);
|
||||
|
||||
const char *data(const string_view &);
|
||||
size_t size(const string_view &);
|
||||
bool empty(const string_view &);
|
||||
bool operator!(const string_view &);
|
||||
|
@ -46,6 +42,13 @@ namespace ircd
|
|||
constexpr string_view operator ""_sv(const char *const literal, const size_t size);
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<> struct std::hash<ircd::string_view>;
|
||||
template<> struct std::less<ircd::string_view>;
|
||||
template<> struct std::equal_to<ircd::string_view>;
|
||||
}
|
||||
|
||||
/// Customized std::string_view (experimental TS / C++17)
|
||||
///
|
||||
/// This class adds iterator-based (char*, char*) construction to std::string_view which otherwise
|
||||
|
@ -185,6 +188,33 @@ struct ircd::string_view
|
|||
using std::string_view::string_view;
|
||||
};
|
||||
|
||||
/// Specialization for std::hash<> participation
|
||||
template<>
|
||||
struct std::hash<ircd::string_view>
|
||||
:std::hash<std::string_view>
|
||||
{
|
||||
using std::hash<std::string_view>::operator();
|
||||
using std::hash<std::string_view>::hash;
|
||||
};
|
||||
|
||||
/// Specialization for std::less<> participation
|
||||
template<>
|
||||
struct std::less<ircd::string_view>
|
||||
:std::less<std::string_view>
|
||||
{
|
||||
using std::less<std::string_view>::operator();
|
||||
using std::less<std::string_view>::less;
|
||||
};
|
||||
|
||||
/// Specialization for std::equal_to<> participation
|
||||
template<>
|
||||
struct std::equal_to<ircd::string_view>
|
||||
:std::equal_to<std::string_view>
|
||||
{
|
||||
using std::equal_to<std::string_view>::operator();
|
||||
using std::equal_to<std::string_view>::equal_to;
|
||||
};
|
||||
|
||||
/// Compile-time conversion from a string literal into a string_view.
|
||||
constexpr ircd::string_view
|
||||
ircd::operator ""_sv(const char *const literal, const size_t size)
|
||||
|
@ -192,139 +222,6 @@ ircd::operator ""_sv(const char *const literal, const size_t size)
|
|||
return string_view{literal, size};
|
||||
}
|
||||
|
||||
template<class T>
|
||||
struct ircd::vector_view
|
||||
{
|
||||
using value_type = T;
|
||||
using pointer = T *;
|
||||
using reference = T &;
|
||||
using difference_type = size_t;
|
||||
using iterator = T *;
|
||||
using const_iterator = const T *;
|
||||
|
||||
T *_data { nullptr };
|
||||
T *_stop { nullptr };
|
||||
|
||||
public:
|
||||
const T *data() const { return _data; }
|
||||
T *data() { return _data; }
|
||||
|
||||
size_t size() const { return std::distance(_data, _stop); }
|
||||
bool empty() const { return !size(); }
|
||||
|
||||
const_iterator begin() const { return data(); }
|
||||
const_iterator end() const { return _stop; }
|
||||
const_iterator cbegin() { return data(); }
|
||||
const_iterator cend() { return _stop; }
|
||||
iterator begin() { return data(); }
|
||||
iterator end() { return _stop; }
|
||||
|
||||
const T &operator[](const size_t &pos) const
|
||||
{
|
||||
return *(data() + pos);
|
||||
}
|
||||
|
||||
T &operator[](const size_t &pos)
|
||||
{
|
||||
return *(data() + pos);
|
||||
}
|
||||
|
||||
const T &at(const size_t &pos) const
|
||||
{
|
||||
if(unlikely(pos >= size()))
|
||||
throw std::out_of_range("vector_view::range_check");
|
||||
|
||||
return operator[](pos);
|
||||
}
|
||||
|
||||
T &at(const size_t &pos)
|
||||
{
|
||||
if(unlikely(pos >= size()))
|
||||
throw std::out_of_range("vector_view::range_check");
|
||||
|
||||
return operator[](pos);
|
||||
}
|
||||
|
||||
vector_view(T *const &start, T *const &stop)
|
||||
:_data{start}
|
||||
,_stop{stop}
|
||||
{}
|
||||
|
||||
vector_view(T *const &start, const size_t &size)
|
||||
:vector_view(start, start + size)
|
||||
{}
|
||||
|
||||
vector_view(const std::initializer_list<T> &list)
|
||||
:vector_view(std::begin(list), std::end(list))
|
||||
{}
|
||||
|
||||
template<class U,
|
||||
class A>
|
||||
vector_view(std::vector<U, A> &v)
|
||||
:vector_view(v.data(), v.size())
|
||||
{}
|
||||
|
||||
template<size_t SIZE>
|
||||
vector_view(T (&buffer)[SIZE])
|
||||
:vector_view(buffer, SIZE)
|
||||
{}
|
||||
|
||||
template<size_t SIZE>
|
||||
vector_view(std::array<T, SIZE> &array)
|
||||
:vector_view(array.data(), array.size())
|
||||
{}
|
||||
|
||||
vector_view() = default;
|
||||
};
|
||||
|
||||
/// string_view -> bytes
|
||||
template<class T>
|
||||
struct ircd::byte_view
|
||||
{
|
||||
string_view s;
|
||||
|
||||
operator const T &() const
|
||||
{
|
||||
if(unlikely(sizeof(T) > s.size()))
|
||||
throw std::bad_cast();
|
||||
|
||||
return *reinterpret_cast<const T *>(s.data());
|
||||
}
|
||||
|
||||
byte_view(const string_view &s = {})
|
||||
:s{s}
|
||||
{
|
||||
if(unlikely(sizeof(T) > s.size()))
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
||||
// bytes -> bytes (completeness)
|
||||
byte_view(const T &t)
|
||||
:s{byte_view<string_view>{t}}
|
||||
{}
|
||||
};
|
||||
|
||||
/// bytes -> string_view. A byte_view<string_view> is raw data of byte_view<T>.
|
||||
///
|
||||
/// This is an important specialization to take note of. When you see
|
||||
/// byte_view<string_view> know that another type's bytes are being represented
|
||||
/// by the string_view if that type is not string_view family itself.
|
||||
template<>
|
||||
struct ircd::byte_view<ircd::string_view>
|
||||
:string_view
|
||||
{
|
||||
template<class T,
|
||||
typename std::enable_if<!std::is_base_of<std::string_view, T>::value, int *>::type = nullptr>
|
||||
byte_view(const T &t)
|
||||
:string_view{reinterpret_cast<const char *>(&t), sizeof(T)}
|
||||
{}
|
||||
|
||||
/// string_view -> string_view (completeness)
|
||||
byte_view(const string_view &t)
|
||||
:string_view{t}
|
||||
{}
|
||||
};
|
||||
|
||||
inline bool
|
||||
ircd::operator!(const string_view &str)
|
||||
{
|
||||
|
@ -355,6 +252,12 @@ ircd::size(const string_view &str)
|
|||
return str.size();
|
||||
}
|
||||
|
||||
inline const char *
|
||||
ircd::data(const string_view &str)
|
||||
{
|
||||
return str.data();
|
||||
}
|
||||
|
||||
template<int (&test)(int)>
|
||||
auto
|
||||
ircd::ctype(const string_view &s)
|
||||
|
|
114
include/ircd/vector_view.h
Normal file
114
include/ircd/vector_view.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* charybdis: 21st Century IRC++d
|
||||
* util.h: Miscellaneous utilities
|
||||
*
|
||||
* Copyright (C) 2016 Charybdis Development Team
|
||||
* Copyright (C) 2016 Jason Volk <jason@zemos.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_VECTOR_VIEW_H
|
||||
|
||||
namespace ircd
|
||||
{
|
||||
template<class T> struct vector_view;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
struct ircd::vector_view
|
||||
{
|
||||
using value_type = T;
|
||||
using pointer = value_type *;
|
||||
using reference = value_type &;
|
||||
using difference_type = size_t;
|
||||
using iterator = value_type *;
|
||||
using const_iterator = const value_type *;
|
||||
|
||||
value_type *_data { nullptr };
|
||||
value_type *_stop { nullptr };
|
||||
|
||||
public:
|
||||
value_type *data() const { return _data; }
|
||||
size_t size() const { return std::distance(_data, _stop); }
|
||||
bool empty() const { return !size(); }
|
||||
|
||||
const_iterator begin() const { return data(); }
|
||||
const_iterator end() const { return _stop; }
|
||||
const_iterator cbegin() { return data(); }
|
||||
const_iterator cend() { return _stop; }
|
||||
iterator begin() { return data(); }
|
||||
iterator end() { return _stop; }
|
||||
|
||||
value_type &operator[](const size_t &pos) const
|
||||
{
|
||||
return *(data() + pos);
|
||||
}
|
||||
|
||||
value_type &at(const size_t &pos) const
|
||||
{
|
||||
if(unlikely(pos >= size()))
|
||||
throw std::out_of_range("vector_view::range_check");
|
||||
|
||||
return operator[](pos);
|
||||
}
|
||||
|
||||
vector_view(value_type *const &start, value_type *const &stop)
|
||||
:_data{start}
|
||||
,_stop{stop}
|
||||
{}
|
||||
|
||||
vector_view(value_type *const &start, const size_t &size)
|
||||
:vector_view(start, start + size)
|
||||
{}
|
||||
|
||||
vector_view(const std::initializer_list<value_type> &list)
|
||||
:vector_view(std::begin(list), std::end(list))
|
||||
{}
|
||||
|
||||
template<class U,
|
||||
class A>
|
||||
vector_view(const std::vector<U, A> &v)
|
||||
:vector_view(v.data(), v.size())
|
||||
{}
|
||||
|
||||
template<class U,
|
||||
class A>
|
||||
vector_view(std::vector<U, A> &v)
|
||||
:vector_view(v.data(), v.size())
|
||||
{}
|
||||
|
||||
template<size_t SIZE>
|
||||
vector_view(value_type (&buffer)[SIZE])
|
||||
:vector_view(buffer, SIZE)
|
||||
{}
|
||||
|
||||
template<class U,
|
||||
size_t SIZE>
|
||||
vector_view(const std::array<U, SIZE> &array)
|
||||
:vector_view(array.data(), array.size())
|
||||
{}
|
||||
|
||||
template<size_t SIZE>
|
||||
vector_view(std::array<value_type, SIZE> &array)
|
||||
:vector_view(array.data(), array.size())
|
||||
{}
|
||||
|
||||
vector_view() = default;
|
||||
};
|
Loading…
Reference in a new issue