diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ece25e..f14097a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,7 @@ if(ENABLE_PROFILING) target_link_options(rexy PRIVATE -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls) endif() -set(LIBREXY_PUBLIC_HEADERS "include/rexy/binary.hpp" "include/rexy/string_base.hpp" "include/rexy/string.hpp" "include/rexy/filerd.hpp" "include/rexy/string_base.tpp" "include/rexy/detail/binary_string_conv.hpp" "include/rexy/detail/default_allocator.hpp" "include/rexy/detail/util.hpp") +set(LIBREXY_PUBLIC_HEADERS "include/rexy/steal.hpp" "include/rexy/binary.hpp" "include/rexy/string_base.hpp" "include/rexy/string.hpp" "include/rexy/filerd.hpp" "include/rexy/string_base.tpp" "include/rexy/detail/binary_string_conv.hpp" "include/rexy/detail/default_allocator.hpp" "include/rexy/detail/util.hpp") target_compile_options(rexy PRIVATE -Wall -Wextra -pedantic -std=c++17) install(TARGETS rexy diff --git a/include/rexy/binary.hpp b/include/rexy/binary.hpp index f1bcf9e..0343ff4 100644 --- a/include/rexy/binary.hpp +++ b/include/rexy/binary.hpp @@ -26,6 +26,7 @@ #include #include //max #include +#include #define STOP_STRICT_ALIAS_WARNING(x) (x) @@ -72,12 +73,16 @@ namespace rexy{ using allocator_type = Allocator; public: constexpr binary_data(void) = default; - binary_data(char* data, size_t size): + [[deprecated]] binary_data(char* data, size_t size): binary_base(data, size){} + binary_data(rexy::steal data, size_t size): + binary_base(data.value(), size){} binary_data(const char* data, size_t size): binary_base(reinterpret_cast(Allocator::copy(data, size)), size){} - binary_data(char* data, size_t cap, size_t size): + [[deprecated]] binary_data(char* data, size_t cap, size_t size): binary_base(data, cap, size){} + binary_data(rexy::steal data, size_t cap, size_t size): + binary_base(data.value(), cap, size){} binary_data(const char* data, size_t cap, size_t size): binary_base(reinterpret_cast(Allocator::copy(data, size)), cap, size){} binary_data(size_t size): diff --git a/include/rexy/steal.hpp b/include/rexy/steal.hpp new file mode 100644 index 0000000..ea3e8d1 --- /dev/null +++ b/include/rexy/steal.hpp @@ -0,0 +1,42 @@ +#ifndef REXY_STEAL_HPP +#define REXY_STEAL_HPP + +#include //forward + +namespace rexy{ + + template + class steal + { + private: + T m_val; + + public: + template + steal(U&& u): + m_val(std::forward(u)){} + + steal(const steal&) = delete; + steal(steal&&) = delete; + steal& operator=(const steal&) = delete; + steal& operator=(steal&&) = delete; + + T&& value(void){ + return std::forward(m_val); + } + const T& value(void)const{ + return m_val; + } + }; + + template + steal(const T&) -> steal; + template + steal(T&&) -> steal; + template + steal(T) -> steal; + template + steal(T*) -> steal; +} + +#endif diff --git a/include/rexy/string_base.hpp b/include/rexy/string_base.hpp index a6674d9..4a6d11f 100644 --- a/include/rexy/string_base.hpp +++ b/include/rexy/string_base.hpp @@ -23,6 +23,8 @@ #include //forward #include //size_t +#include + namespace rexy{ class string_expr{}; @@ -77,10 +79,13 @@ namespace rexy{ public: string_intermediary(void) = default; - string_intermediary(char* data, size_t len); + string_intermediary(rexy::steal data, size_t len); + string_intermediary(rexy::steal data, size_t len, size_t cap); + [[deprecated]] string_intermediary(char* data, size_t len); string_intermediary(const char* data, size_t len); - string_intermediary(char* data, size_t len, size_t cap); + [[deprecated]] string_intermediary(char* data, size_t len, size_t cap); string_intermediary(const char* data); + string_intermediary(rexy::steal); string_intermediary(size_t len); string_intermediary(size_t len, size_t cap); diff --git a/include/rexy/string_base.tpp b/include/rexy/string_base.tpp index 3de578b..ed75cc9 100644 --- a/include/rexy/string_base.tpp +++ b/include/rexy/string_base.tpp @@ -30,9 +30,15 @@ namespace rexy{ string_intermediary::string_intermediary(char* data, size_t len): string_base(data, len){} template + string_intermediary::string_intermediary(rexy::steal data, size_t len): + string_base(data.value(), len){} + template string_intermediary::string_intermediary(char* data, size_t len, size_t cap): string_base(data, len, cap){} template + string_intermediary::string_intermediary(rexy::steal data, size_t len, size_t cap): + string_base(data.value(), len, cap){} + template string_intermediary::string_intermediary(const char* data, size_t len): string_base(reinterpret_cast(len ? Allocator::copy(data, len+1) : nullptr), len) { @@ -48,6 +54,13 @@ namespace rexy{ } } template + string_intermediary::string_intermediary(rexy::steal data): + string_base(data.value() ? strlen(data.value()) : 0) + { + m_data = data.value(); + m_length = m_cap; + } + template string_intermediary::string_intermediary(size_t len): string_base(reinterpret_cast(len ? Allocator::allocate(len+1) : nullptr), len) { diff --git a/src/filerd.cpp b/src/filerd.cpp index fb79649..b882a43 100644 --- a/src/filerd.cpp +++ b/src/filerd.cpp @@ -83,7 +83,7 @@ namespace rexy{ rexy::string filerd::read(size_t bytes){ char* tmp = reinterpret_cast(rexy::string::allocator_type::allocate(bytes)); size_t written = read(tmp, bytes); - return rexy::string(tmp, written); + return rexy::string(rexy::steal(tmp), written); } rexy::string filerd::readln(size_t max){ rexy::string ret; @@ -99,7 +99,7 @@ namespace rexy{ rexy::binary filerd::read_bin(size_t bytes){ char* tmp = reinterpret_cast(rexy::binary::allocator_type::allocate(bytes)); size_t written = read(tmp, bytes); - return rexy::binary(tmp, written, written); + return rexy::binary(rexy::steal(tmp), written, written); } size_t filerd::write(const char* c, size_t bytes){ return fwrite(c, 1, bytes, m_fp);