1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef COMPHELPER_ANYCOMPARE_HXX
25 #define COMPHELPER_ANYCOMPARE_HXX
26 
27 #include "comphelper/comphelperdllapi.h"
28 
29 /** === begin UNO includes === **/
30 #include <com/sun/star/lang/IllegalArgumentException.hpp>
31 #include <com/sun/star/i18n/XCollator.hpp>
32 /** === end UNO includes === **/
33 
34 #include <comphelper/extract.hxx>
35 
36 #include <functional>
37 #include <memory>
38 
39 //......................................................................................................................
40 namespace comphelper
41 {
42 //......................................................................................................................
43 
44     //==================================================================================================================
45 	//= IKeyPredicateLess
46 	//==================================================================================================================
47     class SAL_NO_VTABLE IKeyPredicateLess
48     {
49     public:
50         virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const = 0;
~IKeyPredicateLess()51         virtual ~IKeyPredicateLess() {}
52     };
53 
54 	//==================================================================================================================
55 	//= LessPredicateAdapter
56 	//==================================================================================================================
57     struct LessPredicateAdapter : public ::std::binary_function< ::com::sun::star::uno::Any, ::com::sun::star::uno::Any, bool >
58     {
LessPredicateAdaptercomphelper::LessPredicateAdapter59         LessPredicateAdapter( const IKeyPredicateLess& _predicate )
60             :m_predicate( _predicate )
61         {
62         }
63 
operator ()comphelper::LessPredicateAdapter64         bool operator()( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const
65         {
66             return m_predicate.isLess( _lhs, _rhs );
67         }
68 
69     private:
70         IKeyPredicateLess const &   m_predicate;
71 
72     private:
73         LessPredicateAdapter(); // never implemented
74     };
75 
76 	//==================================================================================================================
77 	//= ScalarPredicateLess
78 	//==================================================================================================================
79     template< typename SCALAR >
80     class ScalarPredicateLess : public IKeyPredicateLess
81     {
82     public:
isLess(::com::sun::star::uno::Any const & _lhs,::com::sun::star::uno::Any const & _rhs) const83         virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const
84         {
85             SCALAR lhs(0), rhs(0);
86             if  (   !( _lhs >>= lhs )
87                 ||  !( _rhs >>= rhs )
88                 )
89                 throw ::com::sun::star::lang::IllegalArgumentException();
90             return lhs < rhs;
91         }
92     };
93 
94 	//==================================================================================================================
95 	//= StringPredicateLess
96 	//==================================================================================================================
97     class StringPredicateLess : public IKeyPredicateLess
98     {
99     public:
isLess(::com::sun::star::uno::Any const & _lhs,::com::sun::star::uno::Any const & _rhs) const100         virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const
101         {
102             ::rtl::OUString lhs, rhs;
103             if  (   !( _lhs >>= lhs )
104                 ||  !( _rhs >>= rhs )
105                 )
106                 throw ::com::sun::star::lang::IllegalArgumentException();
107             return lhs < rhs;
108         }
109     };
110 
111 	//==================================================================================================================
112 	//= StringCollationPredicateLess
113 	//==================================================================================================================
114     class StringCollationPredicateLess : public IKeyPredicateLess
115     {
116     public:
StringCollationPredicateLess(::com::sun::star::uno::Reference<::com::sun::star::i18n::XCollator> const & i_collator)117         StringCollationPredicateLess( ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCollator > const & i_collator )
118             :m_collator( i_collator )
119         {
120         }
121 
isLess(::com::sun::star::uno::Any const & _lhs,::com::sun::star::uno::Any const & _rhs) const122         virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const
123         {
124             ::rtl::OUString lhs, rhs;
125             if  (   !( _lhs >>= lhs )
126                 ||  !( _rhs >>= rhs )
127                 )
128                 throw ::com::sun::star::lang::IllegalArgumentException();
129             return m_collator->compareString( lhs, rhs ) < 0;
130         }
131 
132     private:
133         ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCollator > const m_collator;
134     };
135 
136 	//==================================================================================================================
137 	//= TypePredicateLess
138 	//==================================================================================================================
139     class TypePredicateLess : public IKeyPredicateLess
140     {
141     public:
isLess(::com::sun::star::uno::Any const & _lhs,::com::sun::star::uno::Any const & _rhs) const142         virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const
143         {
144             ::com::sun::star::uno::Type lhs, rhs;
145             if  (   !( _lhs >>= lhs )
146                 ||  !( _rhs >>= rhs )
147                 )
148                 throw ::com::sun::star::lang::IllegalArgumentException();
149             return lhs.getTypeName() < rhs.getTypeName();
150         }
151     };
152 
153 	//==================================================================================================================
154 	//= EnumPredicateLess
155 	//==================================================================================================================
156     class EnumPredicateLess : public IKeyPredicateLess
157     {
158     public:
EnumPredicateLess(::com::sun::star::uno::Type const & _enumType)159         EnumPredicateLess( ::com::sun::star::uno::Type const & _enumType )
160             :m_enumType( _enumType )
161         {
162         }
163 
isLess(::com::sun::star::uno::Any const & _lhs,::com::sun::star::uno::Any const & _rhs) const164         virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const
165         {
166             sal_Int32 lhs(0), rhs(0);
167             if  (   !::cppu::enum2int( lhs, _lhs )
168                 ||  !::cppu::enum2int( rhs, _rhs )
169                 ||  !_lhs.getValueType().equals( m_enumType )
170                 ||  !_rhs.getValueType().equals( m_enumType )
171                 )
172                 throw ::com::sun::star::lang::IllegalArgumentException();
173             return lhs < rhs;
174         }
175 
176     private:
177         ::com::sun::star::uno::Type const   m_enumType;
178     };
179 
180 	//==================================================================================================================
181 	//= InterfacePredicateLess
182 	//==================================================================================================================
183     class InterfacePredicateLess : public IKeyPredicateLess
184     {
185     public:
isLess(::com::sun::star::uno::Any const & _lhs,::com::sun::star::uno::Any const & _rhs) const186         virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const
187         {
188             if  (   ( _lhs.getValueTypeClass() != ::com::sun::star::uno::TypeClass_INTERFACE )
189                 ||  ( _rhs.getValueTypeClass() != ::com::sun::star::uno::TypeClass_INTERFACE )
190                 )
191                 throw ::com::sun::star::lang::IllegalArgumentException();
192 
193             ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > lhs( _lhs, ::com::sun::star::uno::UNO_QUERY );
194             ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > rhs( _rhs, ::com::sun::star::uno::UNO_QUERY );
195             return lhs.get() < rhs.get();
196         }
197     };
198 
199 	//==================================================================================================================
200 	//= getStandardLessPredicate
201 	//==================================================================================================================
202     /** creates a default IKeyPredicateLess instance for the given UNO type
203         @param i_type
204             the type for which a predicate instance should be created
205         @param i_collator
206             specifies a collator instance to use, or <NULL/>. If <NULL/>, strings will be compared using the <code>&lt</code>
207             operator, otherwise the collator will be used. The parameter is ignored if <arg>i_type</arg> does not specify
208             the string type.
209         @return
210             a default implementation of IKeyPredicateLess, which is able to compare values of the given type. If no
211             such default implementation is known for the given type, then <NULL/> is returned.
212     */
213     ::std::auto_ptr< IKeyPredicateLess > COMPHELPER_DLLPUBLIC
214         getStandardLessPredicate(
215             ::com::sun::star::uno::Type const & i_type,
216             ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCollator > const & i_collator
217         );
218 
219 //......................................................................................................................
220 } // namespace comphelper
221 //......................................................................................................................
222 
223 #endif // COMPHELPER_ANYCOMPARE_HXX
224