aboutsummaryrefslogtreecommitdiff
path: root/c/util.h
diff options
context:
space:
mode:
Diffstat (limited to 'c/util.h')
-rw-r--r--c/util.h18
1 files changed, 16 insertions, 2 deletions
diff --git a/c/util.h b/c/util.h
index 561e232..d214f9c 100644
--- a/c/util.h
+++ b/c/util.h
@@ -112,11 +112,19 @@ struct UniqueOk
template <typename T>
struct Buf
{
+ using U = std::remove_const_t<T>;
+
T* data;
size_t c;
+
Buf(T* data, size_t c) noexcept : data(data), c(c) {}
- Buf(std::basic_string<T>& s) noexcept : data(s.data()), c(s.capacity()) {}
- template <size_t N> Buf(T (&data)[N]) noexcept : data(data), c(N) {}
+ Buf(std::enable_if<!std::is_same_v<T, U>, U*> data, size_t c) noexcept
+ : data(data), c(c) {}
+
+ Buf(std::basic_string<U>& s) noexcept : data(s.data()), c(s.capacity()+1) {}
+
+ template <size_t N> inline Buf(T (&data)[N]) noexcept : data(data), c(N) {}
+
operator T*() const noexcept { return data; }
T& operator *() const noexcept { return *data; }
T& operator [](size_t i) const noexcept { return data[i]; }
@@ -142,6 +150,12 @@ inline size_t Len(T (&)[N])
return N-1;
}
+template <typename T>
+inline size_t Len(Buf<T> buf)
+{
+ return buf.c-1;
+}
+
/* Format wide string. */
template<typename... T>
inline std::enable_if_t<!std::disjunction_v<std::is_class<T>...>, int>