LibreOffice Module o3tl (master)  1
any.hxx
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 
10 #ifndef INCLUDED_O3TL_ANY_HXX
11 #define INCLUDED_O3TL_ANY_HXX
12 
13 #include <sal/config.h>
14 
15 #include <cassert>
16 #include <type_traits>
17 #include <utility>
18 
19 #include <optional>
20 
21 #include <com/sun/star/uno/Any.hxx>
22 #include <com/sun/star/uno/RuntimeException.hpp>
23 #include <com/sun/star/uno/Reference.hxx>
24 #include <com/sun/star/uno/XInterface.hpp>
25 #include <cppu/unotype.hxx>
26 #include <rtl/ustring.hxx>
27 #include <sal/types.h>
28 
29 // Some functionality related to css::uno::Any that would ideally be part of
30 // <com/sun/star/uno/Any.hxx>, but (for now) cannot be for some reason.
31 
32 namespace o3tl {
33 
34 namespace detail {
35 
36 struct Void {};
37 
38 template<typename T> struct Optional { using type = T const *; };
39 template<> struct Optional<void> { using type = std::optional<Void const>; };
40 template<> struct Optional<bool> { using type = std::optional<bool const>; };
41 template<> struct Optional<sal_Int8> {
42  using type = std::optional<sal_Int8 const>;
43 };
44 template<> struct Optional<sal_Int16> {
45  using type = std::optional<sal_Int16 const>;
46 };
47 template<> struct Optional<sal_uInt16> {
48  using type = std::optional<sal_uInt16 const>;
49 };
50 template<> struct Optional<sal_Int32> {
51  using type = std::optional<sal_Int32 const>;
52 };
53 template<> struct Optional<sal_uInt32> {
54  using type = std::optional<sal_uInt32 const>;
55 };
56 template<> struct Optional<sal_Int64> {
57  using type = std::optional<sal_Int64 const>;
58 };
59 template<> struct Optional<sal_uInt64> {
60  using type = std::optional<sal_uInt64 const>;
61 };
62 template<> struct Optional<float> {
63  using type = std::optional<float const>;
64 };
65 template<> struct Optional<double> {
66  using type = std::optional<double const>;
67 };
68 template<typename T> struct Optional<css::uno::Reference<T>> {
69  using type = std::optional<css::uno::Reference<T> const>;
70 };
71 template<> struct Optional<css::uno::Reference<css::uno::XInterface>> {
72  using type = css::uno::Reference<css::uno::XInterface> const *;
73 };
74 
75 template<typename> struct IsDerivedReference: std::false_type {};
76 template<typename T> struct IsDerivedReference<css::uno::Reference<T>>:
77  std::true_type
78 {};
79 template<> struct IsDerivedReference<css::uno::Reference<css::uno::XInterface>>:
80  std::false_type
81 {};
82 
83 template<typename> struct IsUnoSequenceType: std::false_type {};
84 template<typename T> struct IsUnoSequenceType<cppu::UnoSequenceType<T>>:
85  std::true_type
86 {};
87 
88 template<typename T> inline std::optional<T const> tryGetConverted(
89  css::uno::Any const & any)
90 {
91  T v;
92  return (any >>= v)
93  ? std::optional<T const>(std::move(v)) : std::optional<T const>();
94 }
95 
96 }
97 
142 template<typename T> inline
143 typename std::enable_if<
144  !(detail::IsDerivedReference<T>::value
145  || detail::IsUnoSequenceType<T>::value
146  || std::is_base_of<css::uno::XInterface, T>::value),
147  typename detail::Optional<T>::type>::type
148 tryAccess(css::uno::Any const & any) {
149  // CHAR, STRING, TYPE, sequence types, enum types, struct types, exception
150  // types, and com.sun.star.uno.XInterface interface type:
151  return cppu::UnoType<T>::get().isAssignableFrom(any.getValueType())
152  ? static_cast<T const *>(any.getValue()) : nullptr;
153 }
154 
156  css::uno::Any const & any)
157 {
158  return any.hasValue()
159  ? std::optional<detail::Void const>()
160  : std::optional<detail::Void const>(detail::Void());
161 }
162 
164  css::uno::Any const & any)
165 {
166  return detail::tryGetConverted<bool>(any);
167 }
168 
170  css::uno::Any const & any)
171 {
172  return detail::tryGetConverted<sal_Int8>(any);
173 }
174 
176  css::uno::Any const & any)
177 {
178  return detail::tryGetConverted<sal_Int16>(any);
179 }
180 
182  css::uno::Any const & any)
183 {
184  return detail::tryGetConverted<sal_uInt16>(any);
185 }
186 
188  css::uno::Any const & any)
189 {
190  return detail::tryGetConverted<sal_Int32>(any);
191 }
192 
194  css::uno::Any const & any)
195 {
196  return detail::tryGetConverted<sal_uInt32>(any);
197 }
198 
200  css::uno::Any const & any)
201 {
202  return detail::tryGetConverted<sal_Int64>(any);
203 }
204 
206  css::uno::Any const & any)
207 {
208  return detail::tryGetConverted<sal_uInt64>(any);
209 }
210 
212  css::uno::Any const & any)
213 {
214  return detail::tryGetConverted<float>(any);
215 }
216 
218  css::uno::Any const & any)
219 {
220  return detail::tryGetConverted<double>(any);
221 }
222 
223 template<> detail::Optional<css::uno::Any>::type tryAccess<css::uno::Any>(
224  css::uno::Any const &) = delete;
225 
226 template<> detail::Optional<sal_Bool>::type tryAccess<sal_Bool>(
227  css::uno::Any const &) = delete;
228 
229 /*
230 
231 // Already prevented by std::is_base_of<css::uno::XInterface, T> requiring T to
232 // be complete:
233 
234 template<> detail::Optional<cppu::UnoVoidType>::type
235 tryAccess<cppu::UnoVoidType>(css::uno::Any const &) = delete;
236 
237 template<> detail::Optional<cppu::UnoUnsignedShortType>::type
238 tryAccess<cppu::UnoUnsignedShortType>(css::uno::Any const &) = delete;
239 
240 template<> detail::Optional<cppu::UnoCharType>::type
241 tryAccess<cppu::UnoCharType>(css::uno::Any const &) = delete;
242 
243 */
244 
245 template<typename T> inline
246 typename std::enable_if<
247  detail::IsDerivedReference<T>::value,
248  typename detail::Optional<T>::type>::type
249 tryAccess(css::uno::Any const & any) {
250  return detail::tryGetConverted<T>(any);
251 }
252 
253 template<typename T> typename detail::Optional<T>::type tryAccess(
254  css::uno::Any const volatile &&) = delete;
255 
279 template<typename T> inline typename detail::Optional<T>::type doAccess(
280  css::uno::Any const & any)
281 {
282  auto opt = tryAccess<T>(any);
283  if (!opt) {
284  throw css::uno::RuntimeException(
285  OUString(
287  &any, cppu::UnoType<T>::get().getTypeLibType()),
288  SAL_NO_ACQUIRE));
289  }
290  return opt;
291 }
292 
313 template<typename T> inline typename detail::Optional<T>::type forceAccess(
314  css::uno::Any const & any)
315 {
316  auto opt = tryAccess<T>(any);
317  assert(opt);
318  return opt;
319 }
320 
321 }
322 
323 #endif
324 
325 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
std::optional< double const > type
Definition: any.hxx:66
signed char sal_Int8
detail::Optional< sal_uInt32 >::type tryAccess< sal_uInt32 >(css::uno::Any const &any)
Definition: any.hxx:193
detail::Optional< sal_Int32 >::type tryAccess< sal_Int32 >(css::uno::Any const &any)
Definition: any.hxx:187
detail::Optional< double >::type tryAccess< double >(css::uno::Any const &any)
Definition: any.hxx:217
detail::Optional< float >::type tryAccess< float >(css::uno::Any const &any)
Definition: any.hxx:211
detail::Optional< sal_uInt16 >::type tryAccess< sal_uInt16 >(css::uno::Any const &any)
Definition: any.hxx:181
std::optional< css::uno::Reference< T > const > type
Definition: any.hxx:69
std::optional< sal_Int16 const > type
Definition: any.hxx:45
detail::Optional< sal_uInt64 >::type tryAccess< sal_uInt64 >(css::uno::Any const &any)
Definition: any.hxx:205
detail::Optional< sal_Int64 >::type tryAccess< sal_Int64 >(css::uno::Any const &any)
Definition: any.hxx:199
std::enable_if< !(detail::IsDerivedReference< T >::value||detail::IsUnoSequenceType< T >::value||std::is_base_of< css::uno::XInterface, T >::value), typename detail::Optional< T >::type >::type tryAccess(css::uno::Any const &any)
Try to access the value of a specific type stored in an Any.
Definition: any.hxx:148
std::optional< float const > type
Definition: any.hxx:63
css::uno::Reference< css::uno::XInterface > const * type
Definition: any.hxx:72
std::optional< sal_Int32 const > type
Definition: any.hxx:51
rtl_uString *SAL_CALL cppu_Any_extraction_failure_msg(uno_Any const *pAny, typelib_TypeDescriptionReference *pType) SAL_THROW_EXTERN_C()
std::optional< sal_uInt16 const > type
Definition: any.hxx:48
css::uno::Type const & get()
detail::Optional< T >::type doAccess(css::uno::Any const &any)
Access the value of a specific type stored in an Any, throwing an exception on failure.
Definition: any.hxx:279
detail::Optional< T >::type forceAccess(css::uno::Any const &any)
Access the value of a specific type stored in an Any, knowing the Any contains a value of a matching ...
Definition: any.hxx:313
std::optional< sal_uInt32 const > type
Definition: any.hxx:54
std::optional< sal_uInt64 const > type
Definition: any.hxx:60
float v
std::optional< sal_Int64 const > type
Definition: any.hxx:57
std::optional< Void const > type
Definition: any.hxx:39
detail::Optional< sal_Int16 >::type tryAccess< sal_Int16 >(css::uno::Any const &any)
Definition: any.hxx:175
detail::Optional< sal_Int8 >::type tryAccess< sal_Int8 >(css::uno::Any const &any)
Definition: any.hxx:169
std::optional< T const > tryGetConverted(css::uno::Any const &any)
Definition: any.hxx:88
detail::Optional< bool >::type tryAccess< bool >(css::uno::Any const &any)
Definition: any.hxx:163
std::optional< sal_Int8 const > type
Definition: any.hxx:42
detail::Optional< void >::type tryAccess< void >(css::uno::Any const &any)
Definition: any.hxx:155
std::optional< bool const > type
Definition: any.hxx:40
T const * type
Definition: any.hxx:38
detail::Optional< sal_Bool >::type tryAccess< sal_Bool >(css::uno::Any const &)=delete
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo