Improve readability and constexpr-ness

This commit is contained in:
rexy712 2020-04-24 12:52:47 -07:00
parent de681d3cd7
commit 4cad6f794d
10 changed files with 147 additions and 179 deletions

View File

@ -14,7 +14,7 @@ option(ENABLE_SHARED "Build shared library" ON)
option(ENABLE_PROFILING "Enable asan" OFF) option(ENABLE_PROFILING "Enable asan" OFF)
mark_as_advanced(ENABLE_PROFILING) mark_as_advanced(ENABLE_PROFILING)
set(SOURCE_LIST "src/binary.cpp" "src/string_base.cpp" "src/filerd.cpp") set(SOURCE_LIST "src/binary.cpp" "src/filerd.cpp")
if(ENABLE_SHARED) if(ENABLE_SHARED)
add_library(rexy SHARED ${SOURCE_LIST}) add_library(rexy SHARED ${SOURCE_LIST})
set_target_properties(rexy PROPERTIES SOVERSION "${librexy_VERSION_MAJOR}.${librexy_VERSION_MINOR}.${librexy_VERSION_REVISION}") set_target_properties(rexy PROPERTIES SOVERSION "${librexy_VERSION_MAJOR}.${librexy_VERSION_MINOR}.${librexy_VERSION_REVISION}")
@ -27,7 +27,8 @@ if(ENABLE_PROFILING)
target_link_options(rexy PRIVATE -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls) target_link_options(rexy PRIVATE -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls)
endif() endif()
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") 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")
set(LIBREXY_DETAIL_HEADERS "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) target_compile_options(rexy PRIVATE -Wall -Wextra -pedantic -std=c++17)
install(TARGETS rexy install(TARGETS rexy
@ -38,6 +39,7 @@ install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/pc/librexy.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
) )
install(FILES ${LIBREXY_PUBLIC_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/rexy/") install(FILES ${LIBREXY_PUBLIC_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/rexy/")
install(FILES ${LIBREXY_DETAIL_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/rexy/detail/")
configure_file( configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/pc/librexy.pc.cmake.in" "${CMAKE_CURRENT_SOURCE_DIR}/pc/librexy.pc.cmake.in"

View File

@ -23,10 +23,9 @@
#include <utility> //move #include <utility> //move
#include <cstring> //memcpy #include <cstring> //memcpy
#include <type_traits> #include <type_traits>
#include <new> #include "detail/util.hpp" //max
#include <rexy/detail/util.hpp> //max #include "detail/default_allocator.hpp"
#include <rexy/detail/default_allocator.hpp> #include "steal.hpp"
#include <rexy/steal.hpp>
#define STOP_STRICT_ALIAS_WARNING(x) (x) #define STOP_STRICT_ALIAS_WARNING(x) (x)
@ -146,34 +145,36 @@ namespace rexy{
struct is_binary_type{ struct is_binary_type{
constexpr static bool value = std::is_same<decltype(is_binary_type_helper(std::declval<typename std::decay<T>::type>())),std::true_type>::value; constexpr static bool value = std::is_same<decltype(is_binary_type_helper(std::declval<typename std::decay<T>::type>())),std::true_type>::value;
}; };
template<class... Ts>
using enable_if_binary = std::enable_if_t<(is_binary_type<Ts>::value && ...),int>;
} }
} template<class Left, class Right, detail::enable_if_binary<Left,Right> = 0>
bool operator==(Left&& l, Right&& r){
template<class Left, class Right, typename std::enable_if<rexy::detail::is_binary_type<Left>::value && rexy::detail::is_binary_type<Right>::value,void>::type* = nullptr>
bool operator==(Left&& l, Right&& r){
return l && r && l.size() == r.size() && l.capacity() == r.capacity() && !memcmp(l.get(), r.get(), l.size()); return l && r && l.size() == r.size() && l.capacity() == r.capacity() && !memcmp(l.get(), r.get(), l.size());
} }
template<class Left, class Right, typename std::enable_if<rexy::detail::is_binary_type<Left>::value && rexy::detail::is_binary_type<Right>::value,void>::type* = nullptr> template<class Left, class Right, detail::enable_if_binary<Left,Right> = 0>
bool operator!=(Left&& l, Right&& r){ bool operator!=(Left&& l, Right&& r){
return !(std::forward<Left>(l) == std::forward<Right>(r)); return !(std::forward<Left>(l) == std::forward<Right>(r));
} }
template<class All, class Alr> template<class All, class Alr>
auto operator+(const rexy::binary_data<All>& l, const rexy::binary_data<Alr>& r){ auto operator+(const rexy::binary_data<All>& l, const rexy::binary_data<Alr>& r){
rexy::binary_data<All> retval(l.size() + r.size()); rexy::binary_data<All> retval(l.size() + r.size());
memcpy(retval.get(), l.get(), l.size()); memcpy(retval.get(), l.get(), l.size());
memcpy(retval.get()+l.size(), r.get(), r.size()); memcpy(retval.get()+l.size(), r.get(), r.size());
return retval; return retval;
} }
template<class All, class Alr> template<class All, class Alr>
decltype(auto) operator+=(rexy::binary_data<All>& l, const rexy::binary_data<Alr>& r){ decltype(auto) operator+=(rexy::binary_data<All>& l, const rexy::binary_data<Alr>& r){
l.resize(l.size() + r.size()); l.resize(l.size() + r.size());
memcpy(l.get()+l.size(), r.get(), r.size()); memcpy(l.get()+l.size(), r.get(), r.size());
return l; return l;
} }
} //namespace rexy
#ifdef REXY_STRING_BASE_HPP #ifdef REXY_STRING_BASE_HPP
#include <rexy/detail/binary_string_conv.hpp> #include "detail/binary_string_conv.hpp"
#endif #endif
#endif #endif

View File

@ -19,53 +19,54 @@
#ifndef REXY_BINARY_STRING_CONV_HPP #ifndef REXY_BINARY_STRING_CONV_HPP
#define REXY_BINARY_STRING_CONV_HPP #define REXY_BINARY_STRING_CONV_HPP
#include <rexy/string.hpp> #include "rexy/string.hpp"
#include <rexy/binary.hpp> #include "rexy/binary.hpp"
#include <cstring> //memcpy
namespace rexy{ namespace rexy{
template<class Al, class Str = rexy::string, typename std::enable_if<rexy::detail::is_concrete_string<Str>::value,void>::type* = nullptr> template<class Al, class Str = rexy::string, detail::enable_if_concrete_string<Str> = 0>
auto binary_to_string(const binary_data<Al>& b){ auto binary_to_string(const binary_data<Al>& b){
Str s(b.size()+1); Str s(b.size()+1);
memcpy(s.get(), b.get(), b.size()); memcpy(s.get(), b.get(), b.size());
s[b.size()] = 0; s[b.size()] = 0;
return s; return s;
} }
template<class Al, class Str = rexy::string, typename std::enable_if<rexy::detail::is_concrete_string<Str>::value && std::is_same<typename std::decay<Al>::type,typename Str::allocator_type>::value,void>::type* = nullptr> template<class Al, class Str = rexy::string, detail::enable_if_concrete_string<Str> = 0, std::enable_if_t<std::is_same<std::decay_t<Al>,typename Str::allocator_type>::value,int> = 0>
auto binary_to_string(binary_data<Al>&& b){ auto binary_to_string(binary_data<Al>&& b){
Str s; Str s;
s.reset(b.get(), b.size()); s.reset(b.get(), b.size());
b.release(); b.release();
return s; return s;
} }
template<class Bin = rexy::binary, typename std::enable_if<rexy::detail::is_binary_type<Bin>::value,void>::type* = nullptr> template<class Bin = rexy::binary, detail::enable_if_binary<Bin> = 0>
auto string_to_binary(const string_base& s){ auto string_to_binary(const string_base& s){
Bin b(s.length()+1); Bin b(s.length()+1);
b.append(s.get(), s.length()+1); b.append(s.get(), s.length()+1);
return b; return b;
} }
template<class Al, class Bin = rexy::binary, typename std::enable_if<rexy::detail::is_binary_type<Bin>::value && std::is_same<typename std::decay<Al>::type,typename Bin::allocator_type>::value,void>::type* = nullptr> template<class Al, class Bin = rexy::binary, detail::enable_if_binary<Bin> = 0, std::enable_if_t<std::is_same<std::decay_t<Al>,typename Bin::allocator_type>::value,int> = 0>
auto string_to_binary(string_intermediary<Al>&& s){ auto string_to_binary(string_intermediary<Al>&& s){
Bin b; Bin b;
b.reset(s.get(), s.length()+1); b.reset(s.get(), s.length()+1);
s.release(); s.release();
return b; return b;
} }
} template<class L, class R, detail::enable_if_binary<L> = 0, detail::enable_if_concrete_string<R> = 0>
template<class L, class R, typename std::enable_if<rexy::detail::is_binary_type<L>::value && rexy::detail::is_concrete_string<R>::value,void>::type* = nullptr> decltype(auto) operator+=(L& l, R&& r){
decltype(auto) operator+=(L& l, R&& r){
l.append(r.get(), r.length()+1); l.append(r.get(), r.length()+1);
return l; return l;
} }
template<class L, class R, typename std::enable_if<rexy::detail::is_binary_type<L>::value && rexy::detail::is_string<R>::value && !rexy::detail::is_concrete_string<R>::value,void>::type* = nullptr> template<class L, class R, detail::enable_if_binary<L> = 0, detail::enable_if_string<R> = 0, std::enable_if_t<!detail::is_concrete_string<R>::value,int> = 0>
decltype(auto) operator+=(L& l, R&& r){ decltype(auto) operator+=(L& l, R&& r){
rexy::string concrete = r; rexy::string concrete = r;
return (l = concrete); return (l = concrete);
} }
template<class L, class R, typename std::enable_if<rexy::detail::is_concrete_string<L>::value && rexy::detail::is_binary_type<R>::value,void>::type* = nullptr> template<class L, class R, detail::enable_if_concrete_string<L> = 0, detail::enable_if_binary<R> = 0>
decltype(auto) operator+=(L& l, R&& r){ decltype(auto) operator+=(L& l, R&& r){
l.resize(l.length(), r.size() + 1); l.resize(l.length(), r.size() + 1);
memcpy(l.get()+l.length()+1, r.get(), r.size()); memcpy(l.get()+l.length()+1, r.get(), r.size());
return l; return l;
} }
} //namespace rexy
#endif #endif

View File

@ -19,7 +19,10 @@
#ifndef REXY_DETAIL_UTIL_HPP #ifndef REXY_DETAIL_UTIL_HPP
#define REXY_DETAIL_UTIL_HPP #define REXY_DETAIL_UTIL_HPP
#include <cstddef> //size_t
namespace rexy::detail{ namespace rexy::detail{
namespace{
//including <algorithm> causes long compile times. so just make my own max instead //including <algorithm> causes long compile times. so just make my own max instead
template<class T> template<class T>
constexpr const T& max(const T& a, const T& b){ constexpr const T& max(const T& a, const T& b){
@ -29,6 +32,47 @@ namespace rexy::detail{
constexpr const T& min(const T& a, const T& b){ constexpr const T& min(const T& a, const T& b){
return (a > b) ? b : a; return (a > b) ? b : a;
} }
}
constexpr size_t cx_strlen(const char* c){
size_t i = 0;
for(;c[i];++i);
return i;
}
constexpr int cx_strcmp(const char* l, const char* r){
using uchar = unsigned char;
for(;*l == *r && *l;++l, ++r);
return (uchar{*l}) - (uchar{*r});
}
} //anonymous namespace
} //namespace detail
//std::swap and std::exchange aren't constexpr until c++20
#if __cplusplus > 201703L
#include <utility>
#define rexy_cx_swap(...) std::swap(__VA_ARGS__)
#define rexy_cx_exchange(...) std::exchange(__VA_ARGS__)
#else
#include <type_traits>
namespace rexy::detail{
namespace{
template<class T>
constexpr void cx_swap(T& a, T& b)noexcept(std::is_nothrow_move_constructible<T>::value &&
std::is_nothrow_move_assignable<T>::value)
{
T tmp = std::move(a);
a = std::move(b);
b = std::move(tmp);
}
template<class T, class U = T>
constexpr T cx_exchange(T& t, U&& u){
T old = std::move(t);
t = std::forward<U>(u);
return old;
}
}
} //namespace detail
#define rexy_cx_swap(...) detail::cx_swap(__VA_ARGS__)
#define rexy_cx_exchange(...) detail::cx_exchange(__VA_ARGS__)
#endif
#endif #endif

View File

@ -22,8 +22,8 @@
#include <cstdio> //FILE #include <cstdio> //FILE
#include <cstddef> //size_t #include <cstddef> //size_t
#include <rexy/string.hpp> #include "string.hpp"
#include <rexy/binary.hpp> #include "binary.hpp"
namespace rexy{ namespace rexy{
@ -34,13 +34,17 @@ namespace rexy{
FILE* m_fp = nullptr; FILE* m_fp = nullptr;
public: public:
filerd(void) = default; constexpr filerd(void) = default;
filerd(const char* f, const char* mode = "r"); filerd(const char* f, const char* mode = "r");
filerd(const filerd&) = delete; filerd(const filerd&) = delete;
filerd(filerd&& f); constexpr filerd(filerd&& f):
m_fp(rexy_cx_exchange(f.m_fp, nullptr)){}
~filerd(void); ~filerd(void);
filerd& operator=(const filerd&) = delete; filerd& operator=(const filerd&) = delete;
filerd& operator=(filerd&& f); constexpr filerd& operator=(filerd&& f){
rexy_cx_swap(m_fp, f.m_fp);
return *this;
}
void reset(FILE* fp = nullptr); void reset(FILE* fp = nullptr);
FILE* release(void); FILE* release(void);

View File

@ -19,8 +19,8 @@
#ifndef REXY_STRING_HPP #ifndef REXY_STRING_HPP
#define REXY_STRING_HPP #define REXY_STRING_HPP
#include <rexy/string_base.hpp> #include "string_base.hpp"
#include <rexy/detail/default_allocator.hpp> #include "detail/default_allocator.hpp"
namespace rexy{ namespace rexy{

View File

@ -23,7 +23,8 @@
#include <utility> //forward #include <utility> //forward
#include <cstdlib> //size_t #include <cstdlib> //size_t
#include <rexy/steal.hpp> #include "steal.hpp"
#include "detail/util.hpp"
namespace rexy{ namespace rexy{
@ -52,7 +53,7 @@ namespace rexy{
public: public:
//Stop managing stored pointer. Does not free. //Stop managing stored pointer. Does not free.
char* release(void); constexpr char* release(void){return rexy_cx_exchange(m_data, nullptr);}
//Length of string not including null terminator //Length of string not including null terminator
constexpr size_t length(void)const{return m_length;} constexpr size_t length(void)const{return m_length;}
@ -65,8 +66,8 @@ namespace rexy{
//true if m_data is not null //true if m_data is not null
constexpr bool valid(void)const{return m_data;} constexpr bool valid(void)const{return m_data;}
char& operator[](size_t i); constexpr char& operator[](size_t i){return m_data[i];}
const char& operator[](size_t i)const; constexpr const char& operator[](size_t i)const{return m_data[i];}
}; };
@ -128,7 +129,6 @@ namespace rexy{
public: public:
template<class T, class U> template<class T, class U>
constexpr string_cat_expr(T&& l, U&& r); constexpr string_cat_expr(T&& l, U&& r);
constexpr string_cat_expr(const string_cat_expr& s);
constexpr string_cat_expr(string_cat_expr&& s); constexpr string_cat_expr(string_cat_expr&& s);
constexpr size_t length(void)const; constexpr size_t length(void)const;
@ -139,30 +139,27 @@ namespace rexy{
}; };
template<class Left, class Right> template<class Left, class Right>
string_cat_expr(Left&, Right&) -> string_cat_expr<Left&,Right&>; string_cat_expr(Left&, Right&) -> string_cat_expr<Left&,Right&>;
template<class Left, class Right>
string_cat_expr(const Left&, const Right&) -> string_cat_expr<const Left&,const Right&>;
template<class Left, class Right> template<class Left, class Right>
string_cat_expr(Left&&,Right&&) -> string_cat_expr<Left,Right>; string_cat_expr(Left&&,Right&&) -> string_cat_expr<Left,Right>;
template<class Left, class Right> template<class Left, class Right>
string_cat_expr(Left&,Right&&) -> string_cat_expr<Left&,Right>; string_cat_expr(Left&,Right&&) -> string_cat_expr<Left&,Right>;
template<class Left, class Right>
string_cat_expr(const Left&,Right&&) -> string_cat_expr<const Left&,Right>;
template<class Left, class Right> template<class Left, class Right>
string_cat_expr(Left&&,Right&) -> string_cat_expr<Left,Right&>; string_cat_expr(Left&&,Right&) -> string_cat_expr<Left,Right&>;
template<class Left, class Right>
string_cat_expr(Left&&,const Right&) -> string_cat_expr<Left,const Right&>;
class static_string : public string_base class static_string : public string_base
{ {
public: public:
constexpr static_string(void) = default; constexpr static_string(void) = default;
constexpr static_string(const char* str, size_t len); constexpr static_string(const char* str, size_t len);
static_string(const char* c); constexpr static_string(const char* c);
constexpr static_string(const static_string& s); constexpr static_string(const static_string& s);
constexpr static_string(static_string&& s); constexpr static_string(static_string&& s);
~static_string(void) = default; ~static_string(void) = default;
static_string& operator=(const char* c); constexpr static_string& operator=(const char* c);
constexpr static_string& operator=(const static_string& s); constexpr static_string& operator=(const static_string& s);
constexpr static_string& operator=(static_string&&); constexpr static_string& operator=(static_string&&);
}; };
@ -200,11 +197,11 @@ namespace rexy{
}; };
} //namespace detail } //namespace detail
template<class Str1, class Str2, detail::enable_if_concrete_string<Str1,Str2> = 0> template<class Str1, class Str2, detail::enable_if_concrete_string<Str1,Str2> = 0>
bool operator==(Str1&& left, Str2&& right){ constexpr bool operator==(Str1&& left, Str2&& right){
return left.valid() && right.valid() && left.length() == right.length() && !strcmp(left.get(), right.get()); return left.valid() && right.valid() && left.length() == right.length() && !detail::cx_strcmp(left.get(), right.get());
} }
template<class Str1, class Str2, detail::enable_if_concrete_string<Str1,Str2> = 0> template<class Str1, class Str2, detail::enable_if_concrete_string<Str1,Str2> = 0>
bool operator!=(Str1&& left, Str2&& right){ constexpr bool operator!=(Str1&& left, Str2&& right){
return !(left == right); return !(left == right);
} }
@ -232,7 +229,7 @@ namespace rexy{
} }
} }
#include <rexy/string_base.tpp> #include "string_base.tpp"
namespace{ namespace{
constexpr inline rexy::static_string operator"" _ss(const char* str, size_t len){ constexpr inline rexy::static_string operator"" _ss(const char* str, size_t len){
@ -241,7 +238,7 @@ namespace{
} }
#ifdef REXY_BINARY_HPP #ifdef REXY_BINARY_HPP
#include <rexy/detail/binary_string_conv.hpp> #include "detail/binary_string_conv.hpp"
#endif #endif
#endif #endif

View File

@ -23,43 +23,9 @@
#include <cstdlib> //memcpy #include <cstdlib> //memcpy
#include <cstring> //strlen, strcpy #include <cstring> //strlen, strcpy
#include <rexy/detail/util.hpp> //max #include "detail/util.hpp" //max
namespace rexy{ namespace rexy{
namespace detail{
namespace{
constexpr size_t cx_strlen(char* c){
size_t i = 0;
for(;c[i];++i);
return i;
}
}
}//namespace detail
//std::swap and std::exchange aren't constexpr until c++20
#if __cplusplus > 201703L
#define cx_swap(...) std::swap(__VA_ARGS__)
#define cx_exchange(...) std::exchange(__VA_ARGS__)
#else
namespace detail{
namespace{
template<class T>
constexpr void cx_swap(T& a, T& b){
T tmp = std::move(a);
a = std::move(b);
b = std::move(tmp);
}
template<class T, class U = T>
constexpr T cx_exchange(T& t, U&& u){
T old = std::move(t);
t = std::forward<U>(u);
return old;
}
}
} //namespace detail
#define cx_swap(...) detail::cx_swap(__VA_ARGS__)
#define cx_exchange(...) detail::cx_exchange(__VA_ARGS__)
#endif
template<class Allocator> template<class Allocator>
constexpr string_intermediary<Allocator>::string_intermediary(void){} constexpr string_intermediary<Allocator>::string_intermediary(void){}
@ -116,7 +82,7 @@ namespace rexy{
string_base(reinterpret_cast<char*>(b.m_length ? Allocator::copy(b.m_data, b.m_length+1) : nullptr), b.m_length, b.m_cap){} string_base(reinterpret_cast<char*>(b.m_length ? Allocator::copy(b.m_data, b.m_length+1) : nullptr), b.m_length, b.m_cap){}
template<class Allocator> template<class Allocator>
constexpr string_intermediary<Allocator>::string_intermediary(string_intermediary&& s): constexpr string_intermediary<Allocator>::string_intermediary(string_intermediary&& s):
string_base(cx_exchange(s.m_data, nullptr), s.m_length, s.m_cap){} string_base(rexy_cx_exchange(s.m_data, nullptr), s.m_length, s.m_cap){}
template<class Allocator> template<class Allocator>
string_intermediary<Allocator>::string_intermediary(const string_base& b): string_intermediary<Allocator>::string_intermediary(const string_base& b):
@ -140,7 +106,7 @@ namespace rexy{
} }
template<class Allocator> template<class Allocator>
constexpr string_intermediary<Allocator>& string_intermediary<Allocator>::operator=(string_intermediary&& s){ constexpr string_intermediary<Allocator>& string_intermediary<Allocator>::operator=(string_intermediary&& s){
cx_swap(m_data, s.m_data); rexy_cx_swap(m_data, s.m_data);
m_length = s.m_length; m_length = s.m_length;
m_cap = s.m_cap; m_cap = s.m_cap;
return *this; return *this;
@ -240,10 +206,6 @@ namespace rexy{
m_l(std::forward<T>(l)), m_l(std::forward<T>(l)),
m_r(std::forward<U>(r)){} m_r(std::forward<U>(r)){}
template<class Left, class Right> template<class Left, class Right>
constexpr string_cat_expr<Left,Right>::string_cat_expr(const string_cat_expr& s):
m_l(s.m_l),
m_r(s.m_r){}
template<class Left, class Right>
constexpr string_cat_expr<Left,Right>::string_cat_expr(string_cat_expr&& s): constexpr string_cat_expr<Left,Right>::string_cat_expr(string_cat_expr&& s):
m_l(std::forward<Left>(s.m_l)), m_l(std::forward<Left>(s.m_l)),
m_r(std::forward<Right>(s.m_r)){} m_r(std::forward<Right>(s.m_r)){}
@ -282,6 +244,13 @@ namespace rexy{
m_length = s.m_length; m_length = s.m_length;
return *this; return *this;
} }
constexpr static_string::static_string(const char* c):
static_string(const_cast<char*>(c), detail::cx_strlen(c)){}
constexpr static_string& static_string::operator=(const char* c){
m_data = const_cast<char*>(c);
m_length = detail::cx_strlen(c);
return *this;
}
constexpr static_string& static_string::operator=(static_string&& s){ constexpr static_string& static_string::operator=(static_string&& s){
m_data = s.m_data; m_data = s.m_data;
m_length = s.m_length; m_length = s.m_length;

View File

@ -25,16 +25,10 @@ namespace rexy{
filerd::filerd(const char* f, const char* mode): filerd::filerd(const char* f, const char* mode):
m_fp(fopen(f, mode)){} m_fp(fopen(f, mode)){}
filerd::filerd(filerd&& f):
m_fp(std::exchange(f.m_fp, nullptr)){}
filerd::~filerd(void){ filerd::~filerd(void){
if(m_fp) if(m_fp)
fclose(m_fp); fclose(m_fp);
} }
filerd& filerd::operator=(filerd&& f){
std::swap(m_fp, f.m_fp);
return *this;
}
void filerd::reset(FILE* fp){ void filerd::reset(FILE* fp){
if(m_fp) if(m_fp)

View File

@ -1,44 +0,0 @@
/**
This file is a part of rexy's general purpose library
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rexy/string_base.hpp"
#include <utility> //exchange, swap
#include <cstdlib> //memcpy
#include <cstring> //strcpy, strlen
namespace rexy{
char* string_base::release(void){
return std::exchange(m_data, nullptr);
}
char& string_base::operator[](size_t i){
return m_data[i];
}
const char& string_base::operator[](size_t i)const{
return m_data[i];
}
static_string::static_string(const char* c):
static_string(const_cast<char*>(c), strlen(c)){}
static_string& static_string::operator=(const char* c){
m_data = const_cast<char*>(c);
m_length = strlen(c);
return *this;
}
}