Add string comparisons

This commit is contained in:
rexy712 2022-07-20 13:31:11 -07:00
parent a21c7312f5
commit dff3303733
2 changed files with 53 additions and 30 deletions

View File

@ -23,6 +23,7 @@
#include <utility> //forward
#include <type_traits> //{false,true}_type, declval, enable_if, remove_reference, decay
#include <algorithm> //lexicographically_compare
#include "../../utility.hpp" //strlen, strncmp
#include "../../traits.hpp"
@ -124,45 +125,61 @@ namespace rexy{
//Compare
template<class Str1, class Str2, std::enable_if_t<are_strings<Str1, Str2>::value,int> = 0>
constexpr bool operator==(Str1&& left, Str2&& right){
constexpr bool operator==(const Str1& left, const Str2& right){
if(left.length() != right.length()){
return false;
}
return !rexy::strncmp(left.c_str(), right.c_str(), left.length()+1);
}
template<class Str1, std::enable_if_t<are_strings<Str1>::value,int> = 0>
constexpr bool operator==(Str1&& left, typename std::decay_t<Str1>::const_pointer right){
constexpr bool operator==(const Str1& left, typename std::decay_t<Str1>::const_pointer right){
if(right == nullptr){
return false;
}
const auto rlen = rexy::strlen(right);
if(rlen != left.length()){
const rexy::basic_string_view rstr(right);
if(rstr.length() != left.length()){
return false;
}
return !rexy::strncmp(left.c_str(), right, rlen+1);
return !rexy::strncmp(left.c_str(), rstr.c_str(), left.length());
}
template<class Str1, std::enable_if_t<are_strings<Str1>::value,int> = 0>
constexpr bool operator==(typename std::decay_t<Str1>::const_pointer left, Str1&& right){
constexpr bool operator==(typename std::decay_t<Str1>::const_pointer left, const Str1& right){
if(left == nullptr){
return false;
}
const auto llen = rexy::strlen(left);
if(llen != right.length()){
const rexy::basic_string_view lstr(left);
if(lstr.length() != right.length()){
return false;
}
return !rexy::strncmp(left, right.c_str(), llen+1);
return !rexy::strncmp(lstr.c_str(), right.c_str(), right.length());
}
template<class Str1, class Str2, std::enable_if_t<are_strings<Str1, Str2>::value,int> = 0>
constexpr bool operator!=(Str1&& left, Str2&& right)noexcept{
return !(std::forward<Str1>(left) == std::forward<Str2>(right));
constexpr bool operator!=(const Str1& left, const Str2& right)noexcept{
return !(left == right);
}
template<class Str1, std::enable_if_t<are_strings<Str1>::value,int> = 0>
constexpr bool operator!=(Str1&& left, typename std::decay_t<Str1>::const_pointer right)noexcept{
return !(std::forward<Str1>(left) == right);
constexpr bool operator!=(const Str1& left, typename std::decay_t<Str1>::const_pointer right)noexcept{
return !(left == right);
}
template<class Str1, std::enable_if_t<are_strings<Str1>::value,int> = 0>
constexpr bool operator!=(typename std::decay_t<Str1>::const_pointer left, Str1&& right)noexcept{
return !(left == std::forward<Str1>(right));
constexpr bool operator!=(typename std::decay_t<Str1>::const_pointer left, const Str1& right)noexcept{
return !(left == right);
}
template<class Str1, class Str2, std::enable_if_t<are_string<Str1,Str2>::value,int> = 0>
constexpr bool operator<(const Str1& left, const Str2& right)noexcept{
return std::lexicographical_compare(left.begin(), left.end(), right.begin(), right.end());
}
template<class Str1, class Str2, std::enable_if_t<are_string<Str1,Str2>::value,int> = 0>
constexpr bool operator<=(const Str1& left, const Str2& right)noexcept{
return !(right < left);
}
template<class Str1, class Str2, std::enable_if_t<are_string<Str1,Str2>::value,int> = 0>
constexpr bool operator>(const Str1& left, const Str2& right)noexcept{
return (right < left);
}
template<class Str1, class Str2, std::enable_if_t<are_string<Str1,Str2>::value,int> = 0>
constexpr bool operator>=(const Str1& left, const Str2& right)noexcept{
return !(left < right);
}
//String + string concat

View File

@ -23,6 +23,7 @@
#include <utility> //forward
#include <type_traits> //decay, is_nothrow_assignable
#include <algorithm> //lexicographically_compare_three_way
#include "../../utility.hpp" //strlen, strncmp
@ -91,45 +92,50 @@ namespace rexy{
//Compare
template<BasicString Str1, BasicString Str2>
constexpr bool operator==(Str1&& left, Str2&& right){
constexpr bool operator==(const Str1& left, const Str2& right){
if(left.length() != right.length()){
return false;
}
return !rexy::strncmp(left.c_str(), right.c_str(), left.length()+1);
}
template<BasicString Str1>
constexpr bool operator==(Str1&& left, typename std::decay_t<Str1>::const_pointer right){
constexpr bool operator==(const Str1& left, typename std::decay_t<Str1>::const_pointer right)noexcept{
if(right == nullptr){
return false;
}
const auto rlen = rexy::strlen(right);
if(rlen != left.length()){
const rexy::basic_string_view rstr(right);
if(rstr.length() != left.length()){
return false;
}
return !rexy::strncmp(left.c_str(), right, rlen+1);
return !rexy::strncmp(left.c_str(), rstr.c_str(), left.length());
}
template<BasicString Str1>
constexpr bool operator==(typename std::decay_t<Str1>::const_pointer left, Str1&& right){
constexpr bool operator==(typename std::decay_t<Str1>::const_pointer left, const Str1& right)noexcept{
if(left == nullptr){
return false;
}
const auto llen = rexy::strlen(left);
if(llen != right.length()){
const rexy::basic_string_view lstr(left);
if(lstr.length() != right.length()){
return false;
}
return !rexy::strncmp(left, right.c_str(), llen+1);
return !rexy::strncmp(lstr.c_str(), right.c_str(), right.length());
}
template<BasicString Str1, BasicString Str2>
constexpr bool operator!=(Str1&& left, Str2&& right){
return !(std::forward<Str1>(left) == std::forward<Str2>(right));
constexpr bool operator!=(const Str1& left, const Str2& right)noexcept{
return !(left == right);
}
template<BasicString Str1>
constexpr bool operator!=(Str1&& left, typename std::decay_t<Str1>::const_pointer right){
return !(std::forward<Str1>(left) == right);
constexpr bool operator!=(const Str1& left, typename std::decay_t<Str1>::const_pointer right)noexcept{
return !(left == right);
}
template<BasicString Str1>
constexpr bool operator!=(typename std::decay_t<Str1>::const_pointer left, Str1&& right){
return !(left == std::forward<Str1>(right));
constexpr bool operator!=(typename std::decay_t<Str1>::const_pointer left, const Str1& right)noexcept{
return !(left == right);
}
template<BasicString Str1, BasicString Str2>
constexpr auto operator<=>(const Str1& left, const Str2& right)noexcept{
return std::lexicographical_compare_three_way(left.begin(), left.end(), right.begin(), right.end());
}
//String + string concat