-
Notifications
You must be signed in to change notification settings - Fork 37
/
Copy pathsmall_string.h
58 lines (53 loc) · 2.32 KB
/
small_string.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#pragma once
// Self contained generic small string implementaton.
#include <cstring>
#include <cstddef>
#include <ostream>
#include <stdexcept>
#include <string_view>
#include <string>
namespace mir
{
template <unsigned int maxLength>
struct SmallString
{
SmallString() noexcept {}
SmallString(std::string_view str)
{
auto length = str.size();
if (length > sizeof(SmallString))
throw std::range_error("Cannot create SmallString: input string exceeds maximum allowed length.");
std::memcpy(_data, str.data(), length);
}
SmallString(const std::string& str) : SmallString((std::string_view)str) {}
SmallString(const char* str) : SmallString(std::string_view(str)) {}
std::string_view str() const noexcept { return std::string_view(_data, _data[maxLength - 1] ? maxLength : std::strlen(_data)); }
operator std::string_view() const noexcept { return str(); }
operator bool() const noexcept { return _data[0] != 0; }
bool operator !() const noexcept { return _data[0] == 0; }
bool operator==(const SmallString& rhs) const noexcept { return memcmp(_data, rhs._data, maxLength) == 0; }
bool operator!=(const SmallString& rhs) const noexcept { return memcmp(_data, rhs._data, maxLength) != 0; }
bool operator<(const SmallString& rhs) const noexcept { return memcmp(_data, rhs._data, maxLength) < 0; }
bool operator<=(const SmallString& rhs) const noexcept { return memcmp(_data, rhs._data, maxLength) <= 0; }
bool operator>(const SmallString& rhs) const noexcept { return memcmp(_data, rhs._data, maxLength) > 0; }
bool operator>=(const SmallString& rhs) const noexcept { return memcmp(_data, rhs._data, maxLength) >= 0; }
private:
char _data[maxLength] = {0};
};
}
namespace std
{
template<unsigned int maxlength>
std::ostream &operator<<(std::ostream &os, const mir::SmallString<maxlength>& ss)
{
return os << ss.str();
}
template <unsigned int maxLength>
struct hash<mir::SmallString<maxLength>>
{
inline size_t operator()(const mir::SmallString<maxLength>& s) const noexcept
{
return std::hash<string_view>()(s.str());
}
};
}