diff options
36 files changed, 283 insertions, 133 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 970c268..d780b2b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,22 @@ +# 0.1.0 + +* Update API-BREAK file; +* Don't call run-time functions from translation-time functions; +* Remove Zap version tags; +* Implement memcpy on ARM; +* Update readme; +* Update logo; +* Implement memcpy on ARM64; +* Update run-time tests; +* Wrap arguments in parantheses in isnan; +* Return the one-after-the-end address of the destination from memfil and fil; +* Increment the extension version; +* Add metaprogramming class for determening pointer types: isptr; +* Fix run-time tests printing equal on inequality; +* Rename API-BREAK to FEATURE-WISHLIST; +* Don't build project in installation script; +* Add development branch 'development'; + # 0.0.2 * Migrate to CMake; diff --git a/API-BREAK.txt b/FEATURE-WISHLIST.txt index 1785310..77658eb 100644 --- a/API-BREAK.txt +++ b/FEATURE-WISHLIST.txt @@ -1,16 +1,21 @@ +The versioning scheme for zP is a major-minor- +patch scheme, where the major version is the +"API" version and the minor is the "extension" +version. Programs that + This file lists potential and planned API- breaks. These are meant to be released simultaneously to minimise the number of extraneous and unnecessary breaks. When enough planned breaks are present, the -features are implemented and the major version -is incremented along with the minor and patch +features are implemented and the API version is +incremented along with the extension and patch versions being reset. Interfaces that are not public (those in the -impl, priv... namespaces) do NOT cause API- -breaks, as their use outside of the library is +det, prv... namespaces) do NOT cause API-b +reaks, as their use outside of the library is both deprecated and causes UB (by our definition). @@ -1 +1,54 @@ -zp +- zP - + + | \ + | \ + | | + | / +<---+--/ + \ | + > | + / | +<---+ + +# ABOUT + +zp is a library for low-level (and high-level) +algorithms and the querying of system details. + The algorithms are - by default - implemented +in C++, but for some targets they may be +implemented in a platform-dependent manner +(such as in an assembly language) for the sake +of performance. Despite this, the language is +still quite early in its development, and these +algorithms may still not be the most efficient. + +# CHANGELOG + +Read: "CHANGELOG.txt" + +# COMPILATION + +Provided are CMake lists files, which + The provided script "getTarget.sh" detects the +target (if supported - otherwise defaults to +"Any") to be passed to CMake. + +## INSTALLATION + +The provided script "install.sh" installs the +library and the (public) headers to the +specified directories: + +./install.sh [build directory] [library directory] [include directory] + +The script automatically builds the project +using pre-defined settings. Note that it does +recursively remove the build directory before +initialising it. + +# COPYRIGHT AND LICENSE + +Copyright 2022-2023 Gabriel Jensen. +The source files of this project are - where +noted - licensed under the second version of +the Mozilla Public License. @@ -22,8 +22,9 @@ int main() { char const * const rtypnm = typeid (rtyp).name(); auto const getval = []<typename typ>(typ const & valref) { - if constexpr (::zp::ischr<typ>) {return static_cast<::zp::i02m>(valref);} - else {return valref;} + if constexpr (::zp::ischr<typ>) {return static_cast<::zp::i02m>(valref);} + else if constexpr (::zp::isptr<typ>) {return reinterpret_cast<void *>(valref);} + else {return valref;} }; auto const lval = getval(lvalref); @@ -35,6 +36,8 @@ int main() { ::fmt::print("\x1B[38;5;161munequal\x1B[0m (at #{})\n",srcloc.line()); //throw ::std::exception {}; ++numerr; + + return; } ::fmt::print("\x1B[38;5;77mequal\x1B[0m\n"); @@ -93,9 +96,19 @@ int main() { [&] { tst("special numbers"); - cmp(::zp::isnan(::zp::nan<float>), true); - cmp(::zp::isnan(::zp::nan<double>), true); - cmp(::zp::isnan(::zp::nan<long double>),true); + cmp(zp_isnanf( zp_nanf), true); + cmp(zp_isnand( zp_nand), true); + cmp(zp_isnanld(zp_nanld),true); + }(); + + [&] { + tst("memory sequences"); + + ::zp::i04 filbuf; + + cmp(::zp::memfil(&filbuf,0xFFu,sizeof (filbuf)),reinterpret_cast<char unsigned *>(&filbuf+0x1u)+0x1u); + + cmp(filbuf,0xFFFFFFFFFFFFFFFFu); }(); [&] { @@ -105,9 +118,9 @@ int main() { wchar_t wstr[] = L"Hello there!"; char32_t str02[] = U"Hello there!"; - ::zp::sz const len = ::zp::strlen(str); - ::zp::sz const wlen = ::zp::strlen(wstr); - ::zp::sz const len02 = ::zp::strlen(str02); + ::zp::sz const len = ::zp_strlen( str); + ::zp::sz const wlen = ::zp_wstrlen( wstr); + ::zp::sz const len02 = ::zp_utf32len(str02); cmp(len, 0xCu); cmp(wlen, 0xCu); @@ -117,9 +130,9 @@ int main() { auto const wbuf = new wchar_t[ wlen]; auto const buf02 = new char32_t[len02]; - cmp(::zp::strcpy(buf, str), len); - cmp(::zp::strcpy(wbuf, wstr), wlen); - cmp(::zp::strcpy(buf02,str02),len02); + cmp(::zp_strcpy( buf, str), len); + cmp(::zp_wstrcpy( wbuf, wstr), wlen); + cmp(::zp_utf32cpy(buf02,str02),len02); delete[] buf; delete[] wbuf; @@ -131,12 +144,12 @@ int main() { char32_t const src[] = U"\U0001F480"; - ::zp::sz const buf8len = ::zp::utf8enclen(src); + ::zp::sz const buf8len = ::zp_utf8enclen(src); cmp(buf8len,0x4u); char8_t * buf8 = new char8_t[buf8len+0x1u]; - ::zp::utf8enc(buf8,src); + ::zp_utf8enc(buf8,src); cmp(buf8[0x0u],0xF0u); cmp(buf8[0x1u],0x9Fu); @@ -144,12 +157,12 @@ int main() { cmp(buf8[0x3u],0x80u); cmp(buf8[0x4u],0x00u); - ::zp::sz const buf02len = ::zp::utf8declen(buf8); + ::zp::sz const buf02len = ::zp_utf8declen(buf8); cmp(buf02len,0x1u); char32_t * buf02 = new char32_t[buf02len+0x1u]; - ::zp::utf8dec(buf02,buf8); + ::zp_utf8dec(buf02,buf8); cmp(buf02[0x0u],0x1F480u); cmp(buf02[0x1u],0x0u); @@ -163,24 +176,24 @@ int main() { char32_t const src[] = U"\U0001F480\u00F0"; - ::zp::sz const buf01len = ::zp::utf16enclen(src); + ::zp::sz const buf01len = ::zp_utf16enclen(src); cmp(buf01len,0x3u); char16_t * buf01 = new char16_t[buf01len+0x1u]; - ::zp::utf16enc(buf01,src); + ::zp_utf16enc(buf01,src); cmp(buf01[0x0u],0xD83Du); cmp(buf01[0x1u],0xDC80u); cmp(buf01[0x2u],0x00F0u); cmp(buf01[0x3u],0x0000u); - ::zp::sz const buf02len = ::zp::utf16declen(buf01); + ::zp::sz const buf02len = ::zp_utf16declen(buf01); cmp(buf02len,0x2u); char32_t * buf02 = new char32_t[buf02len+0x1u]; - ::zp::utf16dec(buf02,buf01); + ::zp_utf16dec(buf02,buf01); cmp(buf02[0x0u],0x1F480u); cmp(buf02[0x1u],0xF0u); @@ -8,6 +8,24 @@ int main() { [] consteval { + static_assert(::zp::isptr<int> == false); + static_assert(::zp::isptr<int *> == true); + static_assert(::zp::isptr<int const *> == true); + static_assert(::zp::isptr<int volatile *> == true); + static_assert(::zp::isptr<int const volatile *> == true); + static_assert(::zp::isptr<int * const> == true); + static_assert(::zp::isptr<int const * const> == true); + static_assert(::zp::isptr<int volatile * const> == true); + static_assert(::zp::isptr<int const volatile * const> == true); + static_assert(::zp::isptr<int * volatile> == true); + static_assert(::zp::isptr<int const * volatile> == true); + static_assert(::zp::isptr<int volatile * volatile> == true); + static_assert(::zp::isptr<int const volatile * volatile> == true); + static_assert(::zp::isptr<int * const volatile> == true); + static_assert(::zp::isptr<int const * const volatile> == true); + static_assert(::zp::isptr<int volatile * const volatile> == true); + static_assert(::zp::isptr<int const volatile * const volatile> == true); + static_assert(::zp::typequ<::zp::sgn<int>, int> == true); static_assert(::zp::typequ<::zp::sgn<int unsigned>,int> == true); @@ -1,10 +1,11 @@ <svg height="48" width="48" xmlns="http://www.w3.org/2000/svg"> <clipPath id="clip61"> - <rect height="48" width="18" x="30" /> + <polygon points="48,0 48,48 30,48 30,18" /> </clipPath> <!-- background --> - <rect fill="#000000" height="48" width="48" /> + <rect fill="#00A470" height="48" width="48" x="00" y="00" /> <!-- letter --> - <polyline fill="none" points="30,12 24,12 24,36 12,36 24,24 12,24 30,24" stroke="#00D143" stroke-linecap="round" stroke-linejoin="round" stroke-width="3" /> - <circle clip-path="url(#clip61)" cx="30" cy="18" fill="none" r="6" stroke="#00D143" stroke-width="3" /> + <polyline fill="none" points="24,12 24,36 12,36 18,30 12,24 30,24" stroke="#FCF4EB" stroke-linecap="round" stroke-linejoin="round" stroke-width="3" /> + <circle clip-path="url(#clip61)" cx="30" cy="18" fill="none" r="6" stroke="#FCF4EB" stroke-width="3" /> + <circle cx="34.243" cy="13.757" fill="#FCF4EB" r="1.5" /> </svg> diff --git a/zp/CMakeLists.txt b/zp/CMakeLists.txt index bc6457e..868a456 100644 --- a/zp/CMakeLists.txt +++ b/zp/CMakeLists.txt @@ -43,19 +43,21 @@ set(ZP_OBJECT_STR_WSTRLEN "source/any/str/wstrlen.cc") set(ZP_OBJECT_STR_WSTRSRH "source/any/str/wstrsrh.cc") if("${ZP_TARGET_}" STREQUAL "Amd64") - set(ZP_OBJECT_BS_SYSCL "source/amd64/bs/syscl.s") - set(ZP_OBJECT_BS_TRP "source/amd64/bs/trp.s") + set(ZP_OBJECT_BS_SYSCL "source/amd64/bs/syscl.s") + set(ZP_OBJECT_BS_TRP "source/amd64/bs/trp.s") - set(ZP_OBJECT_MEM_MEMCPY "source/amd64/mem/memcpy.s") - set(ZP_OBJECT_MEM_MEMFIL "source/amd64/mem/memfil.s") + set(ZP_OBJECT_MEM_MEMCPY "source/amd64/mem/memcpy.s") + set(ZP_OBJECT_MEM_MEMFIL "source/amd64/mem/memfil.s") endif() if("${ZP_TARGET_}" STREQUAL "Arm") - set(ZP_OBJECT_BS_SYSCL "source/arm/bs/syscl.s") + set(ZP_OBJECT_BS_SYSCL "source/arm/bs/syscl.s") + set(ZP_OBJECT_MEM_MEMCPY "source/arm/mem/memcpy.s") endif() if("${ZP_TARGET_}" STREQUAL "Arm64") - set(ZP_OBJECT_BS_SYSCL "source/arm64/bs/syscl.s") + set(ZP_OBJECT_BS_SYSCL "source/arm64/bs/syscl.s") + set(ZP_OBJECT_MEM_MEMCPY "source/arm64/mem/memcpy.s") endif() if("${ZP_TARGET_}" STREQUAL "Ia32") diff --git a/zp/include/zp/bs b/zp/include/zp/bs index 3d85b42..c2d06fd 100644 --- a/zp/include/zp/bs +++ b/zp/include/zp/bs @@ -174,6 +174,29 @@ namespace zp { template<typename ltyp,typename rtyp> constexpr auto typequ = ::zp::det::typequ<ltyp,rtyp>::equ; + namespace det { + template<typename typ> struct isptr {constexpr static bool val = false;}; + + template<typename typ> struct isptr<typ *> {constexpr static auto val = true;}; + template<typename typ> struct isptr<typ const *> {constexpr static auto val = true;}; + template<typename typ> struct isptr<typ volatile *> {constexpr static auto val = true;}; + template<typename typ> struct isptr<typ const volatile *> {constexpr static auto val = true;}; + template<typename typ> struct isptr<typ * const> {constexpr static auto val = true;}; + template<typename typ> struct isptr<typ const * const> {constexpr static auto val = true;}; + template<typename typ> struct isptr<typ volatile * const> {constexpr static auto val = true;}; + template<typename typ> struct isptr<typ const volatile * const> {constexpr static auto val = true;}; + template<typename typ> struct isptr<typ * volatile> {constexpr static auto val = true;}; + template<typename typ> struct isptr<typ const * volatile> {constexpr static auto val = true;}; + template<typename typ> struct isptr<typ volatile * volatile> {constexpr static auto val = true;}; + template<typename typ> struct isptr<typ const volatile * volatile> {constexpr static auto val = true;}; + template<typename typ> struct isptr<typ * const volatile> {constexpr static auto val = true;}; + template<typename typ> struct isptr<typ const * const volatile> {constexpr static auto val = true;}; + template<typename typ> struct isptr<typ volatile * const volatile> {constexpr static auto val = true;}; + template<typename typ> struct isptr<typ const volatile * const volatile> {constexpr static auto val = true;}; + } + + template<typename typ> constexpr auto isptr = ::zp::det::isptr<typ>::val; + template<typename typ> constexpr auto isusgn = ::zp::typequ<typ,char16_t> || ::zp::typequ<typ,char32_t> diff --git a/zp/include/zp/bs.d/isconsteval.ii b/zp/include/zp/bs.d/isconsteval.ii index ec974b7..c3e3d85 100644 --- a/zp/include/zp/bs.d/isconsteval.ii +++ b/zp/include/zp/bs.d/isconsteval.ii @@ -5,9 +5,7 @@ */ constexpr auto ::zp::isconsteval() noexcept -> bool { -#ifdef zp_priv_nconsteval // We use this to implement the run-time API for the "any" architecture. - return true; -#elif zp_priv_hasbuiltin(__builtin_is_constant_evaluated) +#if zp_priv_hasbuiltin(__builtin_is_constant_evaluated) return __builtin_is_constant_evaluated(); #elif __cpp_if_consteval >= 202106 if consteval {return true;} diff --git a/zp/include/zp/bs.h b/zp/include/zp/bs.h index 5757c8a..9fcb82c 100644 --- a/zp/include/zp/bs.h +++ b/zp/include/zp/bs.h @@ -270,7 +270,7 @@ typedef void * zp_nulptrtyp; #endif #define zp_ver ((zp_i04m)+0x0u) // Programs expecting this version will still compile with the current extension version. -#define zp_extver ((zp_i04m)+0x0u) // The extension versions adds functionality without breaking the existing ones. +#define zp_extver ((zp_i04m)+0x1u) // The extension versions adds functionality without breaking the existing ones. // The patch version is not public as it only changes implementation details. #define zp_bytelen ((zp_sz)+0x8u) diff --git a/zp/include/zp/mem b/zp/include/zp/mem index 8404cc0..976a54c 100644 --- a/zp/include/zp/mem +++ b/zp/include/zp/mem @@ -20,7 +20,7 @@ namespace zp { template<typename ltyp,typename rtyp> zp_useres zp_iln inline auto memequ(ltyp const * lbuf,rtyp const * rbuf,::zp::sz const num) noexcept -> bool; - template<typename typ> zp_iln inline auto memfil(typ * dst,char unsigned val,::zp::sz const num) noexcept -> void; + template<typename typ> zp_iln inline auto memfil(typ * dst,char unsigned val,::zp::sz const num) noexcept -> typ *; template<typename typ> zp_useres zp_iln inline auto memsrh(typ * buf,char unsigned val,::zp::sz const num) noexcept -> typ *; template<typename typ> zp_useres zp_iln inline auto memsrh(typ const * buf,char unsigned val,::zp::sz const num) noexcept -> typ const *; @@ -29,7 +29,7 @@ namespace zp { template<typename typ> zp_useres constexpr auto equ(typ const * lbuf,typ const * rbuf,::zp::sz const num) noexcept -> bool; - template<typename typ> constexpr auto fil(typ * dst,typ const val,::zp::sz const num) noexcept -> void; + template<typename typ> constexpr auto fil(typ * dst,typ const val,::zp::sz const num) noexcept -> typ *; template<typename typ> zp_useres constexpr auto srh(typ * buf,typ const val,::zp::sz const num) noexcept -> typ *; template<typename typ> zp_useres constexpr auto srh(typ const * buf,typ const val,::zp::sz const num) noexcept -> typ const *; diff --git a/zp/include/zp/mem.d/cpy.ii b/zp/include/zp/mem.d/cpy.ii index 74f9610..34e92a0 100644 --- a/zp/include/zp/mem.d/cpy.ii +++ b/zp/include/zp/mem.d/cpy.ii @@ -5,10 +5,8 @@ */ template<typename typ> constexpr auto ::zp::cpy(typ * zp_restr dst,typ const * zp_restr src,::zp::sz const num) noexcept -> ::zp::cpyret<typ,typ> { - if (!::zp::isconsteval()) {return ::zp::memcpy(dst,src,num);} - - typ * const zp_restr stop = dst+num; - while (dst != stop) {*dst++ = *src++;} + typ * const zp_restr stp = dst+num; + while (dst != stp) {*dst++ = *src++;} return ::zp::cpyret<typ,typ> {dst,const_cast<typ *>(src),}; } diff --git a/zp/include/zp/mem.d/equ.ii b/zp/include/zp/mem.d/equ.ii index 9ce6a92..4580cf9 100644 --- a/zp/include/zp/mem.d/equ.ii +++ b/zp/include/zp/mem.d/equ.ii @@ -5,9 +5,9 @@ */ template<typename typ> constexpr auto ::zp::equ(typ const * lbuf,typ const * rbuf,::zp::sz const num) noexcept -> bool { - typ const * const stop = lbuf+num; + typ const * const stp = lbuf+num; - while (lbuf != stop) { + while (lbuf != stp) { zp_likly (*lbuf++ != *rbuf++) {return false;} } diff --git a/zp/include/zp/mem.d/fil.ii b/zp/include/zp/mem.d/fil.ii index c57b584..f13da76 100644 --- a/zp/include/zp/mem.d/fil.ii +++ b/zp/include/zp/mem.d/fil.ii @@ -4,8 +4,9 @@ If a copy of the MPL was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0>. */ -template<typename typ> constexpr auto ::zp::fil(typ * dst,typ const val,::zp::sz const num) noexcept -> void { - typ * const stop = dst+num; +template<typename typ> constexpr auto ::zp::fil(typ * dst,typ const val,::zp::sz const num) noexcept -> typ * { + typ * const stp = dst+num; + while (dst != stp) {*dst++ = val;} - while (dst != stop) {*dst++ = val;} + return stp; } diff --git a/zp/include/zp/mem.d/memfil.ii b/zp/include/zp/mem.d/memfil.ii index 92a4fff..4c8d810 100644 --- a/zp/include/zp/mem.d/memfil.ii +++ b/zp/include/zp/mem.d/memfil.ii @@ -4,6 +4,6 @@ If a copy of the MPL was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0>. */ -template<typename typ> inline auto ::zp::memfil(typ * dst,char unsigned const val,::zp::sz const num) noexcept -> void { - ::zp_memfil(dst,val,num); +template<typename typ> inline auto ::zp::memfil(typ * dst,char unsigned const val,::zp::sz const num) noexcept -> typ * { + return static_cast<typ *>(::zp_memfil(dst,val,num)); } diff --git a/zp/include/zp/mem.d/srh.ii b/zp/include/zp/mem.d/srh.ii index 52070a2..8519bb8 100644 --- a/zp/include/zp/mem.d/srh.ii +++ b/zp/include/zp/mem.d/srh.ii @@ -9,9 +9,9 @@ template<typename typ> constexpr auto ::zp::srh(typ * buf,typ val,::zp::sz const } template<typename typ> constexpr auto ::zp::srh(typ const * buf,typ const val,::zp::sz const num) noexcept -> typ const * { - typ const * const stop = buf+num; + typ const * const stp = buf+num; - while (buf != stop) { + while (buf != stp) { typ const * addr = buf++; zp_ulikly (*addr == val) {return addr;} } diff --git a/zp/include/zp/mem.h b/zp/include/zp/mem.h index df1c46f..e3e4c89 100644 --- a/zp/include/zp/mem.h +++ b/zp/include/zp/mem.h @@ -17,9 +17,9 @@ struct zp_cpyret { }; zp_nthrw struct zp_cpyret zp_memcpy(void * zp_restr dst, void const * zp_restr src, zp_sz num); -zp_nthrw zp_useres bool zp_memequ(void const * lbuf,void const * rbuf,zp_sz num); -zp_nthrw void zp_memfil(void * dst, char unsigned val, zp_sz num); -zp_nthrw zp_useres void * zp_memsrh(void const * buf, char unsigned val, zp_sz num); +zp_nthrw zp_useres bool zp_memequ(void const * lbuf,void const * rbuf,zp_sz num); +zp_nthrw void * zp_memfil(void * dst, char unsigned val, zp_sz num); +zp_nthrw zp_useres void * zp_memsrh(void const * buf, char unsigned val, zp_sz num); zp_priv_cdeclend diff --git a/zp/include/zp/mth.h b/zp/include/zp/mth.h index 24adbe5..3a4f79c 100644 --- a/zp/include/zp/mth.h +++ b/zp/include/zp/mth.h @@ -113,9 +113,9 @@ struct zp_vec4ld { }; // is not-a-number -#define zp_isnand( val) ((bool)(val != val)) -#define zp_isnanf( val) ((bool)(val != val)) -#define zp_isnanld(val) ((bool)(val != val)) +#define zp_isnand( val) ((bool)((val) != (val))) +#define zp_isnanf( val) ((bool)((val) != (val))) +#define zp_isnanld(val) ((bool)((val) != (val))) // absolute zp_nthrw zp_useq zp_useres float zp_absf( float val); diff --git a/zp/include/zp/str.d/strcpy.ii b/zp/include/zp/str.d/strcpy.ii index 47fc213..3691e8e 100644 --- a/zp/include/zp/str.d/strcpy.ii +++ b/zp/include/zp/str.d/strcpy.ii @@ -7,14 +7,6 @@ template<typename typ> constexpr auto ::zp::strcpy(typ * dst,typ const * src) noexcept -> ::zp::sz { static_assert(::zp::ischr<typ>,"type must be a character type"); -#if zp_std_cxx17 - if (!::zp::isconsteval()) { - if constexpr (::zp::typequ<typ,char>) {return ::zp_strcpy( dst,src);} - if constexpr (::zp::typequ<typ,wchar_t>) {return ::zp_wstrcpy( dst,src);} - if constexpr (::zp::typequ<typ,char32_t>) {return ::zp_utf32cpy(dst,src);} - } -#endif - auto const dstsrt = dst; while ((*dst++ = *src++) != typ {0x0}) {} diff --git a/zp/include/zp/str.d/strequ.ii b/zp/include/zp/str.d/strequ.ii index 8b3844c..1811445 100644 --- a/zp/include/zp/str.d/strequ.ii +++ b/zp/include/zp/str.d/strequ.ii @@ -7,14 +7,6 @@ template<typename typ> constexpr auto ::zp::strequ(typ const * lstr,typ const * rstr) noexcept -> bool { static_assert(::zp::ischr<typ>,"type must be a character type"); -#if zp_std_cxx17 - if (!::zp::isconsteval()) { - if constexpr (::zp::typequ<typ,char>) {return ::zp_strequ( lstr,rstr);} - if constexpr (::zp::typequ<typ,wchar_t>) {return ::zp_wstrequ( lstr,rstr);} - if constexpr (::zp::typequ<typ,char32_t>) {return ::zp_utf32equ(lstr,rstr);} - } -#endif - for (;;++lstr,++rstr) { zp_likly (*lstr != *rstr) {return false;} zp_ulikly (*lstr == typ {0x0}) {break;} diff --git a/zp/include/zp/str.d/strlen.ii b/zp/include/zp/str.d/strlen.ii index b2287ef..b26765d 100644 --- a/zp/include/zp/str.d/strlen.ii +++ b/zp/include/zp/str.d/strlen.ii @@ -7,14 +7,6 @@ template<typename typ> constexpr auto ::zp::strlen(typ const * str) noexcept -> ::zp::sz { static_assert(::zp::ischr<typ>,"type must be a character type"); // If the string format uses multiple values per character, the number of these values is returned (use utfXdeclen if the number of characters is needed). -#if zp_std_cxx17 - if (!::zp::isconsteval()) { - if constexpr (::zp::typequ<typ,char>) {return ::zp_strlen( str);} - if constexpr (::zp::typequ<typ,wchar_t>) {return ::zp_wstrlen( str);} - if constexpr (::zp::typequ<typ,char32_t>) {return ::zp_utf32len(str);} - } -#endif - auto const srt = str; while (*str++ != typ {0x0}) {} diff --git a/zp/include/zp/str.d/strsrh.ii b/zp/include/zp/str.d/strsrh.ii index 8a7b8d3..59a776a 100644 --- a/zp/include/zp/str.d/strsrh.ii +++ b/zp/include/zp/str.d/strsrh.ii @@ -13,14 +13,6 @@ template<typename typ> constexpr auto ::zp::strsrh(typ * str,typ const chr) noex template<typename typ> constexpr auto ::zp::strsrh(typ const * str,typ const chr) noexcept -> typ const * { static_assert(::zp::ischr<typ>,"type must be a character type"); -#if zp_std_cxx17 - if (!::zp::isconsteval()) { - if constexpr (::zp::typequ<typ,char>) {return ::zp_strsrh( str,chr);} - if constexpr (::zp::typequ<typ,wchar_t>) {return ::zp_wstrsrh( str,chr);} - if constexpr (::zp::typequ<typ,char32_t>) {return ::zp_utf32srh(str,chr);} - } -#endif - for (;;++str) { auto const curchr = *str; diff --git a/zp/include/zp/str.d/utf16dec.ii b/zp/include/zp/str.d/utf16dec.ii index e2bab10..fe6a89a 100644 --- a/zp/include/zp/str.d/utf16dec.ii +++ b/zp/include/zp/str.d/utf16dec.ii @@ -5,10 +5,6 @@ */ constexpr auto ::zp::utf16dec(::zp::c02 * dst,::zp::c01 const * src) noexcept -> void { - if (!::zp::isconsteval()) { - return ::zp_utf16dec(dst,src); - } - for (;;++dst) { auto const hex = *src++; diff --git a/zp/include/zp/str.d/utf16declen.ii b/zp/include/zp/str.d/utf16declen.ii index 9c03620..01a46bb 100644 --- a/zp/include/zp/str.d/utf16declen.ii +++ b/zp/include/zp/str.d/utf16declen.ii @@ -5,10 +5,6 @@ */ constexpr auto ::zp::utf16declen(::zp::c01 const * str) noexcept -> ::zp::sz { - if (!::zp::isconsteval()) { - return ::zp_utf16declen(str); - } - ::zp::sz len = 0x0u; for (;;++len) { diff --git a/zp/include/zp/str.d/utf16enc.ii b/zp/include/zp/str.d/utf16enc.ii index 016f141..f52194c 100644 --- a/zp/include/zp/str.d/utf16enc.ii +++ b/zp/include/zp/str.d/utf16enc.ii @@ -5,10 +5,6 @@ */ constexpr auto ::zp::utf16enc(::zp::c01 * dst,::zp::c02 const * src) noexcept -> void { - if (!::zp::isconsteval()) { - return ::zp_utf16enc(dst,src); - } - for (;;++src) { auto const chr = *src; diff --git a/zp/include/zp/str.d/utf16enclen.ii b/zp/include/zp/str.d/utf16enclen.ii index ed0a420..0758f2e 100644 --- a/zp/include/zp/str.d/utf16enclen.ii +++ b/zp/include/zp/str.d/utf16enclen.ii @@ -5,10 +5,6 @@ */ constexpr auto ::zp::utf16enclen(::zp::c02 const * str) noexcept -> ::zp::sz { - if (!::zp::isconsteval()) { - return ::zp_utf16enclen(str); - } - ::zp::sz len = 0x0u; for (;;++str) { diff --git a/zp/include/zp/str.d/utf8dec.ii b/zp/include/zp/str.d/utf8dec.ii index bc1d8c9..a3913cb 100644 --- a/zp/include/zp/str.d/utf8dec.ii +++ b/zp/include/zp/str.d/utf8dec.ii @@ -5,10 +5,6 @@ */ constexpr auto ::zp::utf8dec(::zp::c02 * dst,::zp::c8 const * src) noexcept -> void { - if (!::zp::isconsteval()) { - return ::zp_utf8dec(dst,src); - } - for (;;++dst) { auto const oct = *src++; diff --git a/zp/include/zp/str.d/utf8declen.ii b/zp/include/zp/str.d/utf8declen.ii index 027fbad..a759a30 100644 --- a/zp/include/zp/str.d/utf8declen.ii +++ b/zp/include/zp/str.d/utf8declen.ii @@ -5,10 +5,6 @@ */ constexpr auto ::zp::utf8declen(::zp::c8 const * str) noexcept -> ::zp::sz { - if (!::zp::isconsteval()) { - return ::zp_utf8declen(str); - } - ::zp::sz len = 0x0u; for (;;++len) { diff --git a/zp/include/zp/str.d/utf8enc.ii b/zp/include/zp/str.d/utf8enc.ii index 42daf23..f3c8c0b 100644 --- a/zp/include/zp/str.d/utf8enc.ii +++ b/zp/include/zp/str.d/utf8enc.ii @@ -5,10 +5,6 @@ */ constexpr auto ::zp::utf8enc(::zp::c8 * dst,::zp::c02 const * src) noexcept -> void { - if (!::zp::isconsteval()) { - return ::zp_utf8enc(dst,src); - } - for (;;++src) { auto const chr = *src; diff --git a/zp/include/zp/str.d/utf8enclen.ii b/zp/include/zp/str.d/utf8enclen.ii index 9f93912..f3e1157 100644 --- a/zp/include/zp/str.d/utf8enclen.ii +++ b/zp/include/zp/str.d/utf8enclen.ii @@ -5,10 +5,6 @@ */ constexpr auto ::zp::utf8enclen(::zp::c02 const * str) noexcept -> ::zp::sz { - if (!::zp::isconsteval()) { - return ::zp_utf8enclen(str); - } - ::zp::sz len = 0x0u; for (;;++str) { diff --git a/zp/include/zp/str.d/win1252dec.ii b/zp/include/zp/str.d/win1252dec.ii index e3914b6..faba1c2 100644 --- a/zp/include/zp/str.d/win1252dec.ii +++ b/zp/include/zp/str.d/win1252dec.ii @@ -5,10 +5,6 @@ */ constexpr auto ::zp::win1252dec(::zp::c02 * dst,::zp::c8 const * src) noexcept -> void { - if (!::zp::isconsteval()) { - return ::zp_win1252dec(dst,src); - } - for (;;++src,++dst) { ::zp::c8 const chr = *src; diff --git a/zp/include/zp/str.d/win1252enc.ii b/zp/include/zp/str.d/win1252enc.ii index 60556c7..d4d714e 100644 --- a/zp/include/zp/str.d/win1252enc.ii +++ b/zp/include/zp/str.d/win1252enc.ii @@ -5,10 +5,6 @@ */ constexpr auto ::zp::win1252enc(::zp::c8 * dst,::zp::c02 const * src) noexcept -> void { - if (!::zp::isconsteval()) { - return ::zp_win1252enc(dst,src); - } - for (;;++src,++dst) { ::zp::c02 const chr = *src; diff --git a/zp/source/amd64/mem/memfil.s b/zp/source/amd64/mem/memfil.s index 1ef09c2..8ce45fc 100644 --- a/zp/source/amd64/mem/memfil.s +++ b/zp/source/amd64/mem/memfil.s @@ -32,4 +32,5 @@ zp_memfil: jmp short .bytfil # goto bytfil; .done: - ret # return + mov rax,rdi + ret # return dst; diff --git a/zp/source/any/mem/memfil.cc b/zp/source/any/mem/memfil.cc index 93111cd..1d8d7f5 100644 --- a/zp/source/any/mem/memfil.cc +++ b/zp/source/any/mem/memfil.cc @@ -6,6 +6,6 @@ #include <zp/mem> -extern "C" zp_nthrw auto zp_memfil(void * const dst,char unsigned const val,::zp::sz const num) -> void { +extern "C" zp_nthrw auto zp_memfil(void * const dst,char unsigned const val,::zp::sz const num) -> void * { return ::zp::fil(static_cast<char unsigned *>(dst),val,num); } diff --git a/zp/source/arm/mem/memcpy.s b/zp/source/arm/mem/memcpy.s new file mode 100644 index 0000000..b07c1f6 --- /dev/null +++ b/zp/source/arm/mem/memcpy.s @@ -0,0 +1,50 @@ +@ Copyright 2022-2023 Gabriel Jensen. +@ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +@ If a copy of the MPL was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0>. + +.syntax unified + +.thumb + +.globl zp_memcpy + +.func +.thumb_func + +zp_memcpy: + @ zp_i02 tmp4; + @ zp_i8 tmp1; + +.wrdcpy: @ wrdcpy:; + @ Check if there are at least four bytes remaining: + cmp r1,0x4 + blt .bytcpy @ if (num < 0x4u) goto bytcpy; + + @ Copy one word: + ldm r0!,{r3} @ tmp4 = *(zp_i02 *)in; /* We use ldm/stm with an exclamation mark after the source/destination as this version saves the incremented address into the register, meaning we don't have to icrement it ourselves. */ + stm r2!,{r3} @ *(zp_i02 *)out = tmp4; + + @ Continue to the next word: + subs r1,0x4 @ num -= 0x4u; + b .wrdcpy @ goto wrdcpy; + +.bytcpy: @ bytcpy:; + @ Check if we have any bytes remaining: + cmp r1,0x0 + beq .done @ if (num == 0x0u) goto done; + + @ Copy one byte: + ldrb r3,[r0] @ tmp1 = *(zp_i8 *)in; + strb r3,[r2] @ *(zp_i8 *)out = tmp1; + + @ Continue to the next byte: + adds r0,0x1 @ ++in; + adds r2,0x1 @ ++out; + subs r1,0x1 @ --num; + b .bytcpy @ goto bytcpy; + +.done: @ done:; + @ Return: + bx lr @ return; + +.endfunc diff --git a/zp/source/arm64/mem/memcpy.s b/zp/source/arm64/mem/memcpy.s new file mode 100644 index 0000000..6d5631e --- /dev/null +++ b/zp/source/arm64/mem/memcpy.s @@ -0,0 +1,40 @@ +// Copyright 2022-2023 Gabriel Jensen. +// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +// If a copy of the MPL was not distributed with this file, You can obtasrc one at <https://mozilla.org/MPL/2.0>. + +.globl zp_cp + +.func + +zp_cp: + // zp_i8 tmp1; + // zp_i04 tmp4; + +.wrdcpy: // wrdcpy:; + cmp x2,0x8 + blt .bytcpy // if (num < 0x8u) goto bytcpy; + + ldr x3,[x1] // tmp8 = *(zp_i04 *)src; + str x3,[x0] // *(zp_i04 *)dst = tmp8; + + add x0,x0,0x8 // dst += 0x8u; + add x1,x1,0x8 // src += 0x8u; + sub x2,x2,0x8 // num -= 0x4u; + b .wrdcpy // goto wrdcpy; + +.bytcpy: // bytcpy:; + cmp x2,0x1 + blt .done // if (num == 0x1u) goto done; + + ldrb w3,[x1] // tmp1 = *(zp_i8 *)src; + strb w3,[x0] // *(zp_i8 *)dst = tmp1; + + add x0,x0,0x1 // ++dst; + add x1,x1,0x1 // ++src; + sub x2,x2,0x1 // --num; + b .bytcpy // goto bytcpy; + +.done: // done:; + ret // return; + +.endfunc |