23#include <typelib/typedescription.hxx>
25#include <com/sun/star/util/Date.hpp>
26#include <com/sun/star/util/Time.hpp>
27#include <com/sun/star/util/DateTime.hpp>
33 using ::com::sun::star::uno::Reference;
34 using ::com::sun::star::uno::Type;
35 using ::com::sun::star::uno::TypeDescription;
36 using ::com::sun::star::uno::TypeClass_CHAR;
37 using ::com::sun::star::uno::TypeClass_BOOLEAN;
38 using ::com::sun::star::uno::TypeClass_BYTE;
39 using ::com::sun::star::uno::TypeClass_SHORT;
40 using ::com::sun::star::uno::TypeClass_UNSIGNED_SHORT;
41 using ::com::sun::star::uno::TypeClass_LONG;
42 using ::com::sun::star::uno::TypeClass_UNSIGNED_LONG;
43 using ::com::sun::star::uno::TypeClass_HYPER;
44 using ::com::sun::star::uno::TypeClass_UNSIGNED_HYPER;
45 using ::com::sun::star::uno::TypeClass_FLOAT;
46 using ::com::sun::star::uno::TypeClass_DOUBLE;
47 using ::com::sun::star::uno::TypeClass_STRING;
48 using ::com::sun::star::uno::TypeClass_TYPE;
49 using ::com::sun::star::uno::TypeClass_ENUM;
50 using ::com::sun::star::uno::TypeClass_INTERFACE;
51 using ::com::sun::star::uno::TypeClass_STRUCT;
52 using ::com::sun::star::i18n::XCollator;
53 using ::com::sun::star::util::Date;
54 using ::com::sun::star::util::Time;
55 using ::com::sun::star::util::DateTime;
56 using ::comphelper::detail::TypeDescriptionRef;
60 class DatePredicateLess :
public IKeyPredicateLess
63 virtual bool isLess( css::uno::Any
const & _lhs, css::uno::Any
const & _rhs )
const override
66 if ( !( _lhs >>= lhs )
69 throw css::lang::IllegalArgumentException(
"bad ordering", css::uno::Reference<css::uno::XInterface>(), -1);
72 if ( lhs.Year < rhs.Year )
74 if ( lhs.Year > rhs.Year )
77 if ( lhs.Month < rhs.Month )
79 if ( lhs.Month > rhs.Month )
82 if ( lhs.Day < rhs.Day )
88 class TimePredicateLess :
public IKeyPredicateLess
91 virtual bool isLess( css::uno::Any
const & _lhs, css::uno::Any
const & _rhs )
const override
94 if ( !( _lhs >>= lhs )
97 throw css::lang::IllegalArgumentException(
"bad ordering", css::uno::Reference<css::uno::XInterface>(), -1);
100 if ( lhs.Hours < rhs.Hours )
102 if ( lhs.Hours > rhs.Hours )
105 if ( lhs.Minutes < rhs.Minutes )
107 if ( lhs.Minutes > rhs.Minutes )
110 if ( lhs.Seconds < rhs.Seconds )
112 if ( lhs.Seconds > rhs.Seconds )
115 if ( lhs.NanoSeconds < rhs.NanoSeconds )
121 class DateTimePredicateLess :
public IKeyPredicateLess
124 virtual bool isLess( css::uno::Any
const & _lhs, css::uno::Any
const & _rhs )
const override
127 if ( !( _lhs >>= lhs )
130 throw css::lang::IllegalArgumentException(
"bad ordering", css::uno::Reference<css::uno::XInterface>(), -1);
133 if ( lhs.Year < rhs.Year )
135 if ( lhs.Year > rhs.Year )
138 if ( lhs.Month < rhs.Month )
140 if ( lhs.Month > rhs.Month )
143 if ( lhs.Day < rhs.Day )
145 if ( lhs.Day > rhs.Day )
148 if ( lhs.Hours < rhs.Hours )
150 if ( lhs.Hours > rhs.Hours )
153 if ( lhs.Minutes < rhs.Minutes )
155 if ( lhs.Minutes > rhs.Minutes )
158 if ( lhs.Seconds < rhs.Seconds )
160 if ( lhs.Seconds > rhs.Seconds )
163 if ( lhs.NanoSeconds < rhs.NanoSeconds )
169 bool anyLess(
void const * lhs, typelib_TypeDescriptionReference * lhsType,
170 void const * rhs, typelib_TypeDescriptionReference * rhsType );
175 std::optional<bool> anyCompare(
void const * lhs, typelib_TypeDescriptionReference * lhsType,
176 void const * rhs, typelib_TypeDescriptionReference * rhsType )
178 if(
anyLess( lhs, lhsType, rhs, rhsType ))
179 return std::optional(
true );
180 if(
anyLess( rhs, rhsType, lhs, lhsType ))
181 return std::optional(
false );
189 if( lhsType == rhsType )
191 if( lhsType->eTypeClass != rhsType->eTypeClass )
192 return lhsType->eTypeClass - rhsType->eTypeClass;
193 if( lhsType->pTypeName->length != rhsType->pTypeName->length )
194 return lhsType->pTypeName->length - rhsType->pTypeName->length;
195 return rtl_ustr_compare( lhsType->pTypeName->buffer, rhsType->pTypeName->buffer );
198 bool anyLess(
void const * lhs, typelib_TypeDescriptionReference * lhsType,
199 void const * rhs, typelib_TypeDescriptionReference * rhsType )
201 if (lhsType->eTypeClass != rhsType->eTypeClass)
202 return lhsType->eTypeClass < rhsType->eTypeClass;
204 if (lhsType->eTypeClass == typelib_TypeClass_VOID) {
207 assert(lhs !=
nullptr);
208 assert(rhs !=
nullptr);
210 switch (lhsType->eTypeClass) {
211 case typelib_TypeClass_INTERFACE:
213 case typelib_TypeClass_STRUCT:
214 case typelib_TypeClass_EXCEPTION: {
215 TypeDescription lhsTypeDescr( lhsType );
216 if (!lhsTypeDescr.is())
217 lhsTypeDescr.makeComplete();
218 if (!lhsTypeDescr.is())
219 throw css::lang::IllegalArgumentException(
"bad ordering", css::uno::Reference<css::uno::XInterface>(), -1);
220 TypeDescription rhsTypeDescr( rhsType );
221 if (!rhsTypeDescr.is())
222 rhsTypeDescr.makeComplete();
223 if (!rhsTypeDescr.is())
224 throw css::lang::IllegalArgumentException(
"bad ordering", css::uno::Reference<css::uno::XInterface>(), -1);
225 int compare = compareTypes( lhsTypeDescr.get(), rhsTypeDescr.get());
229 typelib_CompoundTypeDescription * compType =
230 reinterpret_cast< typelib_CompoundTypeDescription *
>(
231 lhsTypeDescr.get() );
232 sal_Int32 nDescr = compType->nMembers;
234 if (compType->pBaseTypeDescription) {
235 std::optional<bool> subLess = anyCompare(
236 lhs,
reinterpret_cast<
238 compType->pBaseTypeDescription)->pWeakRef,
239 rhs,
reinterpret_cast<
241 compType->pBaseTypeDescription)->pWeakRef);
242 if(subLess.has_value())
246 typelib_TypeDescriptionReference ** ppTypeRefs =
247 compType->ppTypeRefs;
248 sal_Int32 * memberOffsets = compType->pMemberOffsets;
250 for ( sal_Int32 nPos = 0;
nPos < nDescr; ++
nPos )
252 TypeDescriptionRef memberType( ppTypeRefs[ nPos ] );
253 if (!memberType.is())
254 throw css::lang::IllegalArgumentException(
"bad ordering", css::uno::Reference<css::uno::XInterface>(), -1);
255 std::optional<bool> subLess = anyCompare(
256 static_cast< char const *
>(
257 lhs ) + memberOffsets[ nPos ],
258 memberType->pWeakRef,
259 static_cast< char const *
>(
260 rhs ) + memberOffsets[ nPos ],
261 memberType->pWeakRef);
262 if(subLess.has_value())
267 case typelib_TypeClass_SEQUENCE: {
268 uno_Sequence * lhsSeq = *
static_cast< uno_Sequence *
const *
>(lhs);
269 uno_Sequence * rhsSeq = *
static_cast< uno_Sequence *
const *
>(rhs);
270 if( lhsSeq->nElements != rhsSeq->nElements)
271 return lhsSeq->nElements < rhsSeq->nElements;
274 TypeDescriptionRef lhsTypeDescr( lhsType );
275 if (!lhsTypeDescr.is())
276 throw css::lang::IllegalArgumentException(
"bad ordering", css::uno::Reference<css::uno::XInterface>(), -1);
277 TypeDescriptionRef rhsTypeDescr( rhsType );
278 if (!rhsTypeDescr.is())
279 throw css::lang::IllegalArgumentException(
"bad ordering", css::uno::Reference<css::uno::XInterface>(), -1);
280 int compare = compareTypes( lhsTypeDescr.get(), rhsTypeDescr.get());
284 typelib_TypeDescriptionReference * elementTypeRef =
285 reinterpret_cast< typelib_IndirectTypeDescription *
>(lhsTypeDescr.get())->pType;
286 TypeDescriptionRef elementTypeDescr( elementTypeRef );
287 if (!elementTypeDescr.is())
288 throw css::lang::IllegalArgumentException(
"bad ordering", css::uno::Reference<css::uno::XInterface>(), -1);
289 assert( elementTypeDescr.equals( TypeDescriptionRef(
290 reinterpret_cast< typelib_IndirectTypeDescription *
>(lhsTypeDescr.get())->pType )));
292 sal_Int32 nElementSize = elementTypeDescr->nSize;
295 char const * lhsElements = lhsSeq->elements;
296 char const * rhsElements = rhsSeq->elements;
299 std::optional<bool> subLess = anyCompare(
300 lhsElements + (nElementSize * nPos),
301 elementTypeDescr->pWeakRef,
302 rhsElements + (nElementSize * nPos),
303 elementTypeDescr->pWeakRef );
304 if(subLess.has_value())
310 case typelib_TypeClass_ANY: {
313 return anyLess( lhsAny->pData, lhsAny->pType, rhsAny->pData, rhsAny->pType );
315 case typelib_TypeClass_TYPE: {
316 OUString
const & lhsTypeName = OUString::unacquired(
317 &(*
static_cast< typelib_TypeDescriptionReference *
const *
>(lhs))->pTypeName);
318 OUString
const & rhsTypeName = OUString::unacquired(
319 &(*
static_cast< typelib_TypeDescriptionReference *
const *
>(rhs))->pTypeName);
320 return lhsTypeName < rhsTypeName;
322 case typelib_TypeClass_STRING: {
323 OUString
const & lhsStr = OUString::unacquired(
324 static_cast< rtl_uString *
const *
>(lhs) );
325 OUString
const & rhsStr = OUString::unacquired(
326 static_cast< rtl_uString *
const *
>(rhs) );
327 return lhsStr < rhsStr;
329 case typelib_TypeClass_ENUM: {
330 TypeDescription lhsTypeDescr( lhsType );
331 if (!lhsTypeDescr.is())
332 lhsTypeDescr.makeComplete();
333 if (!lhsTypeDescr.is())
334 throw css::lang::IllegalArgumentException(
"bad ordering", css::uno::Reference<css::uno::XInterface>(), -1);
335 TypeDescription rhsTypeDescr( rhsType );
336 if (!rhsTypeDescr.is())
337 rhsTypeDescr.makeComplete();
338 if (!rhsTypeDescr.is())
339 throw css::lang::IllegalArgumentException(
"bad ordering", css::uno::Reference<css::uno::XInterface>(), -1);
340 int compare = compareTypes( lhsTypeDescr.get(), rhsTypeDescr.get());
344 return *
static_cast< int const *
>(lhs) < *
static_cast< int const *
>(rhs);
346 case typelib_TypeClass_BOOLEAN:
347 return *
static_cast< sal_Bool const *
>(lhs) < *
static_cast< sal_Bool const *
>(rhs);
348 case typelib_TypeClass_CHAR:
350 case typelib_TypeClass_FLOAT:
351 return *
static_cast< float const *
>(lhs) < *
static_cast< float const *
>(rhs);
352 case typelib_TypeClass_DOUBLE:
353 return *
static_cast< double const *
>(lhs) < *
static_cast< double const *
>(rhs);
354 case typelib_TypeClass_BYTE:
355 return *
static_cast< sal_Int8 const *
>(lhs) < *
static_cast< sal_Int8 const *
>(rhs);
356 case typelib_TypeClass_SHORT:
357 return *
static_cast< sal_Int16
const *
>(lhs) < *
static_cast< sal_Int16
const *
>(rhs);
358 case typelib_TypeClass_UNSIGNED_SHORT:
359 return *
static_cast< sal_uInt16
const *
>(lhs) < *
static_cast< sal_uInt16
const *
>(rhs);
360 case typelib_TypeClass_LONG:
361 return *
static_cast< sal_Int32
const *
>(lhs) < *
static_cast< sal_Int32
const *
>(rhs);
362 case typelib_TypeClass_UNSIGNED_LONG:
363 return *
static_cast< sal_uInt32
const *
>(lhs) < *
static_cast< sal_uInt32
const *
>(rhs);
364 case typelib_TypeClass_HYPER:
365 return *
static_cast< sal_Int64
const *
>(lhs) < *
static_cast< sal_Int64
const *
>(rhs);
366 case typelib_TypeClass_UNSIGNED_HYPER:
367 return *
static_cast< sal_uInt64
const *
>(lhs) < *
static_cast< sal_uInt64
const *
>(rhs);
380 std::unique_ptr< IKeyPredicateLess > pComparator;
381 switch ( i_type.getTypeClass() )
386 case TypeClass_BOOLEAN:
392 case TypeClass_SHORT:
395 case TypeClass_UNSIGNED_SHORT:
401 case TypeClass_UNSIGNED_LONG:
404 case TypeClass_HYPER:
407 case TypeClass_UNSIGNED_HYPER:
410 case TypeClass_FLOAT:
413 case TypeClass_DOUBLE:
416 case TypeClass_STRING:
417 if ( i_collator.is() )
428 case TypeClass_INTERFACE:
431 case TypeClass_STRUCT:
433 pComparator.reset(
new DatePredicateLess );
435 pComparator.reset(
new TimePredicateLess );
437 pComparator.reset(
new DateTimePredicateLess );
445 bool anyLess( css::uno::Any
const & lhs, css::uno::Any
const & rhs)
447 return anyLess( lhs.getValue(), lhs.getValueTypeRef(), rhs.getValue(), rhs.getValueTypeRef());
struct _typelib_TypeDescription typelib_TypeDescription
std::unique_ptr< IKeyPredicateLess > getStandardLessPredicate(Type const &i_type, Reference< XCollator > const &i_collator)
bool anyLess(css::uno::Any const &lhs, css::uno::Any const &rhs)
Compare two Anys.
SbxDecimal::CmpResult compare(SAL_UNUSED_PARAMETER const SbxDecimal &, SAL_UNUSED_PARAMETER const SbxDecimal &)