Skip to content

Commit bbff52c

Browse files
committed
mapi_lib: switch propval_compare to use operator<=> and yield strong_ordering
1 parent b041d63 commit bbff52c

File tree

4 files changed

+64
-66
lines changed

4 files changed

+64
-66
lines changed

exch/exmdb/db_engine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1396,7 +1396,7 @@ static std::strong_ordering db_engine_compare_propval(proptype_t proptype,
13961396
return std::strong_ordering::less;
13971397
if (pvalue1 != nullptr && pvalue2 == nullptr)
13981398
return std::strong_ordering::greater;
1399-
return propval_compare(pvalue1, pvalue2, proptype) <=> 0;
1399+
return propval_compare(pvalue1, pvalue2, proptype);
14001400
}
14011401

14021402
static BOOL db_engine_insert_categories(sqlite3 *psqlite,

exch/nsp/nsp_interface.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <algorithm>
55
#include <cassert>
66
#include <cerrno>
7+
#include <compare>
78
#include <cstdint>
89
#include <cstdio>
910
#include <cstdlib>
@@ -1053,7 +1054,7 @@ static BOOL nsp_interface_match_node(const ab_tree::ab_node &node,
10531054
pfilter->res.res_not.pres) ? TRUE : false;
10541055
case RES_CONTENT:
10551056
return FALSE;
1056-
case RES_PROPERTY:
1057+
case RES_PROPERTY: {
10571058
if (pfilter->res.res_property.pprop == nullptr)
10581059
return TRUE;
10591060
// XXX RESTRICTION_PROPERTY::comparable check
@@ -1103,26 +1104,27 @@ static BOOL nsp_interface_match_node(const ab_tree::ab_node &node,
11031104
temp_buff, std::size(temp_buff)) != ecSuccess)
11041105
return FALSE;
11051106
// XXX: convert to RESTRICTION_PROPERTY::eval
1106-
int cmp;
1107+
auto cmp = std::strong_ordering::equivalent;
11071108
switch (PROP_TYPE(pfilter->res.res_property.proptag)) {
11081109
case PT_SHORT:
1109-
cmp = three_way_compare(prop_val.value.s, pfilter->res.res_property.pprop->value.s);
1110+
cmp = prop_val.value.s <=> pfilter->res.res_property.pprop->value.s;
11101111
break;
11111112
case PT_LONG:
1112-
cmp = three_way_compare(prop_val.value.l, pfilter->res.res_property.pprop->value.l);
1113+
cmp = prop_val.value.l <=> pfilter->res.res_property.pprop->value.l;
11131114
break;
11141115
case PT_BOOLEAN:
1115-
cmp = three_way_compare(prop_val.value.b, pfilter->res.res_property.pprop->value.b);
1116+
cmp = prop_val.value.b <=> pfilter->res.res_property.pprop->value.b;
11161117
break;
11171118
case PT_STRING8:
11181119
case PT_UNICODE:
1119-
cmp = strcasecmp(prop_val.value.pstr, pfilter->res.res_property.pprop->value.pstr);
1120+
cmp = strcasecmp(prop_val.value.pstr, pfilter->res.res_property.pprop->value.pstr) <=> 0;
11201121
break;
11211122
default:
11221123
mlog(LV_ERR, "E-1967: unhandled proptag %xh", pfilter->res.res_property.proptag);
11231124
return false;
11241125
}
11251126
return three_way_eval(pfilter->res.res_property.relop, cmp) ? TRUE : false;
1127+
}
11261128
case RES_PROPCOMPARE:
11271129
return FALSE;
11281130
case RES_BITMASK:

include/gromox/propval.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
extern GX_EXPORT void *propval_dup(uint16_t type, const void *);
77
extern GX_EXPORT void propval_free(uint16_t type, void *pvalue);
88
extern GX_EXPORT uint32_t propval_size(uint16_t type, const void *pvalue) __attribute__((nonnull(2)));
9-
extern GX_EXPORT int propval_compare(const void *, const void *, gromox::proptype_t) __attribute__((nonnull(1,2)));
9+
extern GX_EXPORT std::strong_ordering propval_compare(const void *, const void *, gromox::proptype_t) __attribute__((nonnull(1,2)));
1010
extern GX_EXPORT bool propval_compare_relop(relop, gromox::proptype_t, const void *, const void *) __attribute__((nonnull(3,4)));
1111
extern GX_EXPORT std::strong_ordering SVREID_compare(const SVREID *, const SVREID *);
1212
namespace gromox {
13-
extern GX_EXPORT bool three_way_eval(enum relop, int);
13+
extern GX_EXPORT bool three_way_eval(enum relop, std::strong_ordering);
1414
extern GX_EXPORT bool propval_compare_relop_nullok(relop, uint16_t proptype, const void *, const void *);
1515
}

lib/mapi/propval.cpp

Lines changed: 53 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -555,65 +555,59 @@ template<typename T> static std::strong_ordering fpcompare(T x, T y)
555555
* However, for RELOP_EQ and RELOP_NE, comparisons between PT_MV_x
556556
* and PT_x should be added [GXL-361].
557557
*/
558-
int propval_compare(const void *pvalue1, const void *pvalue2, proptype_t proptype)
558+
std::strong_ordering propval_compare(const void *pvalue1, const void *pvalue2,
559+
proptype_t proptype)
559560
{
560561
#define MVCOMPARE2(field, retype) do { \
561-
cmp = three_way_compare(a->count, b->count); \
562+
cmp = a->count <=> b->count; \
562563
if (cmp != 0) \
563564
break; \
564565
for (size_t jj = 0; jj < a->count; ++jj) { \
565-
cmp = three_way_compare(static_cast<retype>((a->field)[jj]), \
566-
static_cast<retype>((b->field)[jj])); \
566+
cmp = static_cast<retype>((a->field)[jj]) <=> \
567+
static_cast<retype>((b->field)[jj]); \
567568
if (cmp != 0) \
568569
break; \
569570
} \
570571
} while (false)
571572

572-
int cmp = -2;
573+
auto cmp = std::strong_ordering::equivalent;
573574
switch (proptype) {
574575
case PT_SHORT:
575-
return three_way_compare(*static_cast<const uint16_t *>(pvalue1),
576-
*static_cast<const uint16_t *>(pvalue2));
576+
return *static_cast<const uint16_t *>(pvalue1) <=>
577+
*static_cast<const uint16_t *>(pvalue2);
577578
case PT_LONG:
578579
case PT_ERROR:
579-
return three_way_compare(*static_cast<const uint32_t *>(pvalue1),
580-
*static_cast<const uint32_t *>(pvalue2));
580+
return *static_cast<const uint32_t *>(pvalue1) <=>
581+
*static_cast<const uint32_t *>(pvalue2);
581582
case PT_BOOLEAN:
582-
return three_way_compare(!!*static_cast<const uint8_t *>(pvalue1),
583-
!!*static_cast<const uint8_t *>(pvalue2));
583+
return !!*static_cast<const uint8_t *>(pvalue1) <=>
584+
!!*static_cast<const uint8_t *>(pvalue2);
584585
case PT_CURRENCY:
585586
case PT_I8:
586587
case PT_SYSTIME:
587-
return three_way_compare(*static_cast<const uint64_t *>(pvalue1),
588-
*static_cast<const uint64_t *>(pvalue2));
589-
case PT_FLOAT: {
590-
auto c = fpcompare(*static_cast<const float *>(pvalue1),
591-
*static_cast<const float *>(pvalue2));
592-
return c == 0 ? 0 : c < 0 ? -1 : 1;
593-
}
588+
return *static_cast<const uint64_t *>(pvalue1) <=>
589+
*static_cast<const uint64_t *>(pvalue2);
590+
case PT_FLOAT:
591+
return fpcompare(*static_cast<const float *>(pvalue1),
592+
*static_cast<const float *>(pvalue2));
594593
case PT_DOUBLE:
595-
case PT_APPTIME: {
596-
auto c = fpcompare(*static_cast<const double *>(pvalue1),
597-
*static_cast<const double *>(pvalue2));
598-
return c == 0 ? 0 : c < 0 ? -1 : 1;
599-
}
594+
case PT_APPTIME:
595+
return fpcompare(*static_cast<const double *>(pvalue1),
596+
*static_cast<const double *>(pvalue2));
600597
case PT_STRING8:
601598
case PT_UNICODE:
602599
case PT_GXI_STRING:
603600
return strcasecmp(static_cast<const char *>(pvalue1),
604-
static_cast<const char *>(pvalue2));
605-
case PT_CLSID: {
606-
auto c = *static_cast<const GUID *>(pvalue1) <=> *static_cast<const GUID *>(pvalue2);
607-
return c == 0 ? 0 : c < 0 ? -1 : 1;
608-
}
609-
case PT_BINARY: {
610-
auto c = *static_cast<const BINARY *>(pvalue1) <=> *static_cast<const BINARY *>(pvalue2);
611-
return c == 0 ? 0 : c < 0 ? -1 : 1;
612-
}
613-
case PT_SVREID: {
614-
auto c = *static_cast<const SVREID *>(pvalue1) <=> *static_cast<const SVREID *>(pvalue2);
615-
return c == 0 ? 0 : c < 0 ? -1 : 1;
616-
}
601+
static_cast<const char *>(pvalue2)) <=> 0;
602+
case PT_CLSID:
603+
return *static_cast<const GUID *>(pvalue1) <=>
604+
*static_cast<const GUID *>(pvalue2);
605+
case PT_BINARY:
606+
return *static_cast<const BINARY *>(pvalue1) <=>
607+
*static_cast<const BINARY *>(pvalue2);
608+
case PT_SVREID:
609+
return *static_cast<const SVREID *>(pvalue1) <=>
610+
*static_cast<const SVREID *>(pvalue2);
617611
case PT_MV_SHORT: {
618612
auto a = static_cast<const SHORT_ARRAY *>(pvalue1);
619613
auto b = static_cast<const SHORT_ARRAY *>(pvalue2);
@@ -637,39 +631,39 @@ int propval_compare(const void *pvalue1, const void *pvalue2, proptype_t proptyp
637631
case PT_MV_FLOAT: {
638632
auto a = static_cast<const FLOAT_ARRAY *>(pvalue1);
639633
auto b = static_cast<const FLOAT_ARRAY *>(pvalue2);
640-
cmp = three_way_compare(a->count, b->count);
634+
cmp = a->count <=> b->count;
641635
if (cmp != 0)
642636
break;
643637
for (size_t i = 0; i < a->count; ++i) {
644-
auto c = fpcompare(a->mval[i], b->mval[i]);
645-
if (c != 0)
646-
return c < 0 ? -1 : 1;
638+
cmp = fpcompare(a->mval[i], b->mval[i]);
639+
if (cmp != 0)
640+
break;
647641
}
648642
break;
649643
}
650644
case PT_MV_DOUBLE:
651645
case PT_MV_APPTIME: {
652646
auto a = static_cast<const DOUBLE_ARRAY *>(pvalue1);
653647
auto b = static_cast<const DOUBLE_ARRAY *>(pvalue2);
654-
cmp = three_way_compare(a->count, b->count);
648+
cmp = a->count <=> b->count;
655649
if (cmp != 0)
656650
break;
657651
for (size_t i = 0; i < a->count; ++i) {
658-
auto c = fpcompare(a->mval[i], b->mval[i]);
659-
if (c != 0)
660-
return c < 0 ? -1 : 1;
652+
cmp = fpcompare(a->mval[i], b->mval[i]);
653+
if (cmp != 0)
654+
break;
661655
}
662656
break;
663657
}
664658
case PT_MV_STRING8:
665659
case PT_MV_UNICODE: {
666660
auto sa1 = static_cast<const STRING_ARRAY *>(pvalue1);
667661
auto sa2 = static_cast<const STRING_ARRAY *>(pvalue2);
668-
cmp = three_way_compare(sa1->count, sa2->count);
662+
cmp = sa1->count <=> sa2->count;
669663
if (cmp != 0)
670664
break;
671665
for (size_t i = 0; i < sa1->count; ++i) {
672-
cmp = strcasecmp(sa1->ppstr[i], sa2->ppstr[i]);
666+
cmp = strcasecmp(sa1->ppstr[i], sa2->ppstr[i]) <=> 0;
673667
if (cmp != 0)
674668
break;
675669
}
@@ -678,26 +672,26 @@ int propval_compare(const void *pvalue1, const void *pvalue2, proptype_t proptyp
678672
case PT_MV_CLSID: {
679673
auto bv1 = static_cast<const GUID_ARRAY *>(pvalue1);
680674
auto bv2 = static_cast<const GUID_ARRAY *>(pvalue2);
681-
cmp = three_way_compare(bv1->count, bv2->count);
675+
cmp = bv1->count <=> bv2->count;
682676
if (cmp != 0)
683677
break;
684678
for (size_t i = 0; i < bv1->count; ++i) {
685-
auto c = bv1->pguid[i] <=> bv2->pguid[i];
686-
if (c != 0)
687-
return c < 0 ? -1 : 1;
679+
cmp = bv1->pguid[i] <=> bv2->pguid[i];
680+
if (cmp != 0)
681+
break;
688682
}
689683
break;
690684
}
691685
case PT_MV_BINARY: {
692686
auto bv1 = static_cast<const BINARY_ARRAY *>(pvalue1);
693687
auto bv2 = static_cast<const BINARY_ARRAY *>(pvalue2);
694-
cmp = three_way_compare(bv1->count, bv2->count);
688+
cmp = bv1->count <=> bv2->count;
695689
if (cmp != 0)
696690
break;
697691
for (size_t i = 0; i < bv1->count; ++i) {
698-
auto c = bv1->pbin[i] <=> bv2->pbin[i];
699-
if (c != 0)
700-
return c < 0 ? -1 : 1;
692+
cmp = bv1->pbin[i] <=> bv2->pbin[i];
693+
if (cmp != 0)
694+
break;
701695
}
702696
break;
703697
}
@@ -731,14 +725,16 @@ bool propval_compare_relop_nullok(enum relop relop, proptype_t proptype,
731725
/*
732726
* EXC2019-compatible behavior: absent values sort before anything
733727
* else, and compare equal to another absent property.
728+
* (See also: db_engine_compare_propval)
734729
*/
735730
if (a == nullptr)
736-
return three_way_eval(relop, b == nullptr ? 0 : -1);
737-
return b == nullptr ? three_way_eval(relop, 1) :
731+
return three_way_eval(relop, b == nullptr ?
732+
std::strong_ordering::equal : std::strong_ordering::less);
733+
return b == nullptr ? three_way_eval(relop, std::strong_ordering::greater) :
738734
propval_compare_relop(relop, proptype, a, b);
739735
}
740736

741-
bool three_way_eval(relop r, int order)
737+
bool three_way_eval(relop r, std::strong_ordering order)
742738
{
743739
switch (r) {
744740
case RELOP_LT: return order < 0;

0 commit comments

Comments
 (0)