LibreOffice Module comphelper (master)  1
anycompare.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <memory>
22 
23 #include <com/sun/star/util/Date.hpp>
24 #include <com/sun/star/util/Time.hpp>
25 #include <com/sun/star/util/DateTime.hpp>
26 
27 namespace comphelper
28 {
29  using ::com::sun::star::uno::Reference;
30  using ::com::sun::star::uno::Type;
31  using ::com::sun::star::uno::TypeClass_CHAR;
32  using ::com::sun::star::uno::TypeClass_BOOLEAN;
33  using ::com::sun::star::uno::TypeClass_BYTE;
34  using ::com::sun::star::uno::TypeClass_SHORT;
35  using ::com::sun::star::uno::TypeClass_UNSIGNED_SHORT;
36  using ::com::sun::star::uno::TypeClass_LONG;
37  using ::com::sun::star::uno::TypeClass_UNSIGNED_LONG;
38  using ::com::sun::star::uno::TypeClass_HYPER;
39  using ::com::sun::star::uno::TypeClass_UNSIGNED_HYPER;
40  using ::com::sun::star::uno::TypeClass_FLOAT;
41  using ::com::sun::star::uno::TypeClass_DOUBLE;
42  using ::com::sun::star::uno::TypeClass_STRING;
43  using ::com::sun::star::uno::TypeClass_TYPE;
44  using ::com::sun::star::uno::TypeClass_ENUM;
45  using ::com::sun::star::uno::TypeClass_INTERFACE;
46  using ::com::sun::star::uno::TypeClass_STRUCT;
47  using ::com::sun::star::i18n::XCollator;
48  using ::com::sun::star::util::Date;
49  using ::com::sun::star::util::Time;
50  using ::com::sun::star::util::DateTime;
51 
52  namespace {
53 
54  class DatePredicateLess : public IKeyPredicateLess
55  {
56  public:
57  virtual bool isLess( css::uno::Any const & _lhs, css::uno::Any const & _rhs ) const override
58  {
59  Date lhs, rhs;
60  if ( !( _lhs >>= lhs )
61  || !( _rhs >>= rhs )
62  )
63  throw css::lang::IllegalArgumentException();
64  // FIXME Timezone?
65 
66  if ( lhs.Year < rhs.Year )
67  return true;
68  if ( lhs.Year > rhs.Year )
69  return false;
70 
71  if ( lhs.Month < rhs.Month )
72  return true;
73  if ( lhs.Month > rhs.Month )
74  return false;
75 
76  if ( lhs.Day < rhs.Day )
77  return true;
78  return false;
79  }
80  };
81 
82  class TimePredicateLess : public IKeyPredicateLess
83  {
84  public:
85  virtual bool isLess( css::uno::Any const & _lhs, css::uno::Any const & _rhs ) const override
86  {
87  Time lhs, rhs;
88  if ( !( _lhs >>= lhs )
89  || !( _rhs >>= rhs )
90  )
91  throw css::lang::IllegalArgumentException();
92  // FIXME Timezone?
93 
94  if ( lhs.Hours < rhs.Hours )
95  return true;
96  if ( lhs.Hours > rhs.Hours )
97  return false;
98 
99  if ( lhs.Minutes < rhs.Minutes )
100  return true;
101  if ( lhs.Minutes > rhs.Minutes )
102  return false;
103 
104  if ( lhs.Seconds < rhs.Seconds )
105  return true;
106  if ( lhs.Seconds > rhs.Seconds )
107  return false;
108 
109  if ( lhs.NanoSeconds < rhs.NanoSeconds )
110  return true;
111  return false;
112  }
113  };
114 
115  class DateTimePredicateLess : public IKeyPredicateLess
116  {
117  public:
118  virtual bool isLess( css::uno::Any const & _lhs, css::uno::Any const & _rhs ) const override
119  {
120  DateTime lhs, rhs;
121  if ( !( _lhs >>= lhs )
122  || !( _rhs >>= rhs )
123  )
124  throw css::lang::IllegalArgumentException();
125  // FIXME Timezone?
126 
127  if ( lhs.Year < rhs.Year )
128  return true;
129  if ( lhs.Year > rhs.Year )
130  return false;
131 
132  if ( lhs.Month < rhs.Month )
133  return true;
134  if ( lhs.Month > rhs.Month )
135  return false;
136 
137  if ( lhs.Day < rhs.Day )
138  return true;
139  if ( lhs.Day > rhs.Day )
140  return false;
141 
142  if ( lhs.Hours < rhs.Hours )
143  return true;
144  if ( lhs.Hours > rhs.Hours )
145  return false;
146 
147  if ( lhs.Minutes < rhs.Minutes )
148  return true;
149  if ( lhs.Minutes > rhs.Minutes )
150  return false;
151 
152  if ( lhs.Seconds < rhs.Seconds )
153  return true;
154  if ( lhs.Seconds > rhs.Seconds )
155  return false;
156 
157  if ( lhs.NanoSeconds < rhs.NanoSeconds )
158  return true;
159  return false;
160  }
161  };
162 
163  }
164 
165  std::unique_ptr< IKeyPredicateLess > getStandardLessPredicate( Type const & i_type, Reference< XCollator > const & i_collator )
166  {
167  std::unique_ptr< IKeyPredicateLess > pComparator;
168  switch ( i_type.getTypeClass() )
169  {
170  case TypeClass_CHAR:
171  pComparator.reset( new ScalarPredicateLess< sal_Unicode > );
172  break;
173  case TypeClass_BOOLEAN:
174  pComparator.reset( new ScalarPredicateLess< bool > );
175  break;
176  case TypeClass_BYTE:
177  pComparator.reset( new ScalarPredicateLess< sal_Int8 > );
178  break;
179  case TypeClass_SHORT:
180  pComparator.reset( new ScalarPredicateLess< sal_Int16 > );
181  break;
182  case TypeClass_UNSIGNED_SHORT:
183  pComparator.reset( new ScalarPredicateLess< sal_uInt16 > );
184  break;
185  case TypeClass_LONG:
186  pComparator.reset( new ScalarPredicateLess< sal_Int32 > );
187  break;
188  case TypeClass_UNSIGNED_LONG:
189  pComparator.reset( new ScalarPredicateLess< sal_uInt32 > );
190  break;
191  case TypeClass_HYPER:
192  pComparator.reset( new ScalarPredicateLess< sal_Int64 > );
193  break;
194  case TypeClass_UNSIGNED_HYPER:
195  pComparator.reset( new ScalarPredicateLess< sal_uInt64 > );
196  break;
197  case TypeClass_FLOAT:
198  pComparator.reset( new ScalarPredicateLess< float > );
199  break;
200  case TypeClass_DOUBLE:
201  pComparator.reset( new ScalarPredicateLess< double > );
202  break;
203  case TypeClass_STRING:
204  if ( i_collator.is() )
205  pComparator.reset( new StringCollationPredicateLess( i_collator ) );
206  else
207  pComparator.reset( new StringPredicateLess );
208  break;
209  case TypeClass_TYPE:
210  pComparator.reset( new TypePredicateLess );
211  break;
212  case TypeClass_ENUM:
213  pComparator.reset( new EnumPredicateLess( i_type ) );
214  break;
215  case TypeClass_INTERFACE:
216  pComparator.reset( new InterfacePredicateLess );
217  break;
218  case TypeClass_STRUCT:
219  if ( i_type.equals( ::cppu::UnoType< Date >::get() ) )
220  pComparator.reset( new DatePredicateLess );
221  else if ( i_type.equals( ::cppu::UnoType< Time >::get() ) )
222  pComparator.reset( new TimePredicateLess );
223  else if ( i_type.equals( ::cppu::UnoType< DateTime >::get() ) )
224  pComparator.reset( new DateTimePredicateLess );
225  break;
226  default:
227  break;
228  }
229  return pComparator;
230  }
231 
232  bool anyLess( css::uno::Any const & lhs, css::uno::Any const & rhs)
233  {
234  auto lhsTypeClass = lhs.getValueType().getTypeClass();
235  auto rhsTypeClass = rhs.getValueType().getTypeClass();
236  if (lhsTypeClass != rhsTypeClass)
237  return lhsTypeClass < rhsTypeClass;
238  std::unique_ptr< IKeyPredicateLess > pred = getStandardLessPredicate( lhs.getValueType(), Reference< XCollator >() );
239  if (!pred) // type==VOID
240  return false;
241  return pred->isLess(lhs, rhs);
242  }
243 
244 } // namespace comphelper
245 
246 
247 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Type
bool anyLess(css::uno::Any const &lhs, css::uno::Any const &rhs)
Compare two Anys.
Definition: anycompare.cxx:232
std::unique_ptr< IKeyPredicateLess > getStandardLessPredicate(Type const &i_type, Reference< XCollator > const &i_collator)
Definition: anycompare.cxx:165