From 2235acae6124f4bef457673dff4eba57b00960fb Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Tue, 7 Jul 2020 11:58:45 -0700 Subject: [PATCH] ircd::buffer: Split copy() and move() suites to files. --- include/ircd/buffer/buffer.h | 136 ++--------------------------------- include/ircd/buffer/copy.h | 98 +++++++++++++++++++++++++ include/ircd/buffer/move.h | 70 ++++++++++++++++++ 3 files changed, 174 insertions(+), 130 deletions(-) create mode 100644 include/ircd/buffer/copy.h create mode 100644 include/ircd/buffer/move.h diff --git a/include/ircd/buffer/buffer.h b/include/ircd/buffer/buffer.h index 11573bed1..b8076a933 100644 --- a/include/ircd/buffer/buffer.h +++ b/include/ircd/buffer/buffer.h @@ -66,7 +66,7 @@ namespace ircd::buffer template std::reverse_iterator rbegin(const buffer &buffer); template std::reverse_iterator rend(const buffer &buffer); - // Single buffer observers + // Single buffer observer utils template bool null(const buffer &buffer); template bool full(const buffer &buffer); template bool empty(const buffer &buffer); @@ -78,17 +78,11 @@ namespace ircd::buffer size_t overlap_count(const const_buffer &, const const_buffer &); bool overlap(const const_buffer &, const const_buffer &); - // Single buffer mutators + // Single buffer mutator utils template size_t consume(buffer &buffer, const size_t &bytes); template buffer &operator+=(buffer &buffer, const size_t &bytes); - char *©(char *&dest, char *const &stop, char src); - char *©(char *&dest, char *const &stop, const const_buffer &src); - char *&move(char *&dest, char *const &stop, const const_buffer &src); - size_t copy(const mutable_buffer &dst, const char src); - size_t copy(const mutable_buffer &dst, const const_buffer &src); - size_t move(const mutable_buffer &dst, const const_buffer &src); - template size_t copy(const mutable_buffer &dst, const char (&)[SIZE]); - template size_t move(const mutable_buffer &dst, const char (&)[SIZE]); + + // other tools size_t reverse(const mutable_buffer &dst, const const_buffer &src); void reverse(const mutable_buffer &buf); size_t zero(const mutable_buffer &buf); @@ -109,6 +103,8 @@ namespace ircd::buffer::buffers #include "buffer_base.h" #include "mutable_buffer.h" #include "const_buffer.h" +#include "copy.h" +#include "move.h" #include "fixed_buffer.h" #include "window_buffer.h" #include "parse_buffer.h" @@ -260,126 +256,6 @@ ircd::buffer::reverse(const mutable_buffer &dst, return ret; } -template -#ifndef __clang__ -__attribute__((error -#else -__attribute__((unavailable -#endif -( - "Move source is an array. Is this a string literal? Do you want to move the \\0?" - " Disambiguate this by typing the source string_view or const_buffer." -))) -inline size_t -ircd::buffer::move(const mutable_buffer &dst, - const char (&buf)[SIZE]) -{ - return move(dst, const_buffer{buf}); -} - -template -#ifndef __clang__ -__attribute__((error -#else -__attribute__((unavailable -#endif -( - "Copy source is an array. Is this a string literal? Do you want to copy the \\0?" - " Disambiguate this by typing the source string_view or const_buffer." -))) -inline size_t -ircd::buffer::copy(const mutable_buffer &dst, - const char (&buf)[SIZE]) -{ - return copy(dst, const_buffer{buf}); -} - -inline size_t -ircd::buffer::move(const mutable_buffer &dst, - const const_buffer &src) -{ - char *const &s(begin(dst)), *e(s); - e = move(e, end(dst), src); - assert(std::distance(s, e) >= 0); - return std::distance(s, e); -} - -inline size_t -ircd::buffer::copy(const mutable_buffer &dst, - const const_buffer &src) -{ - char *const &s(begin(dst)), *e(s); - e = copy(e, end(dst), src); - assert(std::distance(s, e) >= 0); - return std::distance(s, e); -} - -inline size_t -ircd::buffer::copy(const mutable_buffer &dst, - const char src) -{ - char *const &s(begin(dst)), *e(s); - e = copy(e, end(dst), src); - assert(std::distance(s, e) >= 0); - return std::distance(s, e); -} - -inline char *& -__attribute__((always_inline)) -ircd::buffer::move(char *&dest, - char *const &stop, - const const_buffer &src) -{ - assert(dest <= stop); - const size_t remain(std::distance(dest, stop)); - const size_t cpsz(std::min(size(src), remain)); - assert(cpsz <= size(src)); - assert(cpsz <= remain); - #if __has_builtin(__builtin_memmove_inline) && !defined(RB_GENERIC) - __builtin_memmove_inline(dest, data(src), cpsz); - #else - __builtin_memmove(dest, data(src), cpsz); - #endif - dest += cpsz; - assert(dest <= stop); - return dest; -} - -inline char *& -__attribute__((always_inline)) -ircd::buffer::copy(char *&dest, - char *const &stop, - const const_buffer &src) -{ - assert(dest <= stop); - const size_t remain(std::distance(dest, stop)); - const size_t cpsz(std::min(size(src), remain)); - assert(!overlap(const_buffer(dest, cpsz), src)); - assert(cpsz <= size(src)); - assert(cpsz <= remain); - #if __has_builtin(__builtin_memcpy_inline) && !defined(RB_GENERIC) - __builtin_memcpy_inline(dest, data(src), cpsz); - #else - __builtin_memcpy(dest, data(src), cpsz); - #endif - dest += cpsz; - assert(dest <= stop); - return dest; -} - -inline char *& -ircd::buffer::copy(char *&dest, - char *const &stop, - char src) -{ - assert(dest <= stop); - const bool cpsz(dest != stop); - (cpsz? *dest : src) = src; - dest += cpsz; - assert(dest <= stop); - return dest; -} - template inline ircd::buffer::buffer & __attribute__((always_inline)) diff --git a/include/ircd/buffer/copy.h b/include/ircd/buffer/copy.h new file mode 100644 index 000000000..39826eb3e --- /dev/null +++ b/include/ircd/buffer/copy.h @@ -0,0 +1,98 @@ +// The Construct +// +// Copyright (C) The Construct Developers, Authors & Contributors +// Copyright (C) 2016-2020 Jason Volk +// +// 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. The +// full license for this software is available in the LICENSE file. + +#pragma once +#define HAVE_IRCD_BUFFER_COPY_H + +namespace ircd::buffer +{ + // copy single character + char *©(char *&dest, char *const &stop, char src); + size_t copy(const mutable_buffer &dst, const char src); + + // copy non-overlapping regions + char *©(char *&dest, char *const &stop, const const_buffer &src); + size_t copy(const mutable_buffer &dst, const const_buffer &src); + template size_t copy(const mutable_buffer &dst, const char (&)[SIZE]); +} + +template +#ifndef __clang__ +__attribute__((error +#else +__attribute__((unavailable +#endif +( + "Copy source is an array. Is this a string literal? Do you want to copy the \\0?" + " Disambiguate this by typing the source string_view or const_buffer." +))) +inline size_t +ircd::buffer::copy(const mutable_buffer &dst, + const char (&buf)[SIZE]) +{ + return copy(dst, const_buffer{buf}); +} + +inline size_t +ircd::buffer::copy(const mutable_buffer &dst, + const const_buffer &src) +{ + char *const &s(begin(dst)), *e(s); + e = copy(e, end(dst), src); + assert(std::distance(s, e) >= 0); + return std::distance(s, e); +} + +inline size_t +ircd::buffer::copy(const mutable_buffer &dst, + const char src) +{ + char *const &s(begin(dst)), *e(s); + e = copy(e, end(dst), src); + assert(std::distance(s, e) >= 0); + return std::distance(s, e); +} + +inline char *& +__attribute__((always_inline)) +ircd::buffer::copy(char *&dest, + char *const &stop, + const const_buffer &src) +{ + assert(dest <= stop); + const size_t remain(std::distance(dest, stop)); + const size_t cpsz(std::min(size(src), remain)); + assert(!overlap(const_buffer(dest, cpsz), src)); + assert(cpsz <= size(src)); + assert(cpsz <= remain); + + #if __has_builtin(__builtin_memcpy_inline) && !defined(RB_GENERIC) + __builtin_memcpy_inline(dest, data(src), cpsz); + #else + __builtin_memcpy(dest, data(src), cpsz); + #endif + + dest += cpsz; + assert(dest <= stop); + return dest; +} + +inline char *& +ircd::buffer::copy(char *&dest, + char *const &stop, + char src) +{ + assert(dest <= stop); + const bool cpsz(dest != stop); + (cpsz? *dest : src) = src; + dest += cpsz; + assert(dest <= stop); + return dest; +} diff --git a/include/ircd/buffer/move.h b/include/ircd/buffer/move.h new file mode 100644 index 000000000..083eb3264 --- /dev/null +++ b/include/ircd/buffer/move.h @@ -0,0 +1,70 @@ +// The Construct +// +// Copyright (C) The Construct Developers, Authors & Contributors +// Copyright (C) 2016-2020 Jason Volk +// +// 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. The +// full license for this software is available in the LICENSE file. + +#pragma once +#define HAVE_IRCD_BUFFER_MOVE_H + +// copy overlapping regions +namespace ircd::buffer +{ + char *&move(char *&dest, char *const &stop, const const_buffer &src); + size_t move(const mutable_buffer &dst, const const_buffer &src); + template size_t move(const mutable_buffer &dst, const char (&)[SIZE]); +} + +template +#ifndef __clang__ +__attribute__((error +#else +__attribute__((unavailable +#endif +( + "Move source is an array. Is this a string literal? Do you want to move the \\0?" + " Disambiguate this by typing the source string_view or const_buffer." +))) +inline size_t +ircd::buffer::move(const mutable_buffer &dst, + const char (&buf)[SIZE]) +{ + return move(dst, const_buffer{buf}); +} + +inline size_t +ircd::buffer::move(const mutable_buffer &dst, + const const_buffer &src) +{ + char *const &s(begin(dst)), *e(s); + e = move(e, end(dst), src); + assert(std::distance(s, e) >= 0); + return std::distance(s, e); +} + +inline char *& +__attribute__((always_inline)) +ircd::buffer::move(char *&dest, + char *const &stop, + const const_buffer &src) +{ + assert(dest <= stop); + const size_t remain(std::distance(dest, stop)); + const size_t cpsz(std::min(size(src), remain)); + assert(cpsz <= size(src)); + assert(cpsz <= remain); + + #if __has_builtin(__builtin_memmove_inline) && !defined(RB_GENERIC) + __builtin_memmove_inline(dest, data(src), cpsz); + #else + __builtin_memmove(dest, data(src), cpsz); + #endif + + dest += cpsz; + assert(dest <= stop); + return dest; +}