1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #ifndef INCLUDED_COM_SUN_STAR_UNO_ANY_HXX
20 #define INCLUDED_COM_SUN_STAR_UNO_ANY_HXX
22 #include "sal/config.h"
31 #include "com/sun/star/uno/Any.h"
33 #include "uno/sequence2.h"
34 #include "com/sun/star/uno/Type.hxx"
35 #include "com/sun/star/uno/Reference.h"
36 #include "com/sun/star/uno/genfunc.hxx"
37 #include "com/sun/star/uno/RuntimeException.hpp"
38 #include "cppu/cppudllapi.h"
39 #include "cppu/unotype.hxx"
41 extern "C" CPPU_DLLPUBLIC rtl_uString
* SAL_CALL
cppu_Any_extraction_failure_msg(
42 uno_Any
const * pAny
, typelib_TypeDescriptionReference
* pType
)
57 ::uno_any_construct( this, NULL
, NULL
, cpp_acquire
);
62 inline Any::Any( T
const & value
)
64 ::uno_type_any_construct(
65 this, const_cast<T
*>(&value
),
66 ::cppu::getTypeFavourUnsigned(&value
).getTypeLibType(),
70 inline Any::Any( bool value
)
73 ::uno_type_any_construct(
74 this, &b
, cppu::UnoType
<bool>::get().getTypeLibType(),
78 #if defined LIBO_INTERNAL_ONLY
79 template<typename T1
, typename T2
>
80 Any::Any(rtl::OUStringConcat
<T1
, T2
> && value
):
81 Any(rtl::OUString(std::move(value
)))
85 inline Any::Any( const Any
& rAny
)
87 ::uno_type_any_construct( this, rAny
.pData
, rAny
.pType
, cpp_acquire
);
90 inline Any::Any( const void * pData_
, const Type
& rType
)
92 ::uno_type_any_construct(
93 this, const_cast< void * >( pData_
), rType
.getTypeLibType(),
97 inline Any::Any( const void * pData_
, typelib_TypeDescription
* pTypeDescr
)
100 this, const_cast< void * >( pData_
), pTypeDescr
, cpp_acquire
);
103 inline Any::Any( const void * pData_
, typelib_TypeDescriptionReference
* pType_
)
105 ::uno_type_any_construct(
106 this, const_cast< void * >( pData_
), pType_
, cpp_acquire
);
115 inline Any
& Any::operator = ( const Any
& rAny
)
119 ::uno_type_any_assign(
120 this, rAny
.pData
, rAny
.pType
,
121 cpp_acquire
, cpp_release
);
126 #if defined LIBO_INTERNAL_ONLY
130 inline void moveAnyInternals(Any
& from
, Any
& to
) {
131 uno_any_construct(&to
, nullptr, nullptr, &cpp_acquire
);
132 std::swap(from
.pType
, to
.pType
);
133 std::swap(from
.pData
, to
.pData
);
134 std::swap(from
.pReserved
, to
.pReserved
);
135 if (to
.pData
== &from
.pReserved
) {
136 to
.pData
= &to
.pReserved
;
138 // This leaves from.pData (where "from" is now VOID) dangling to somewhere (cf.
139 // CONSTRUCT_EMPTY_ANY, cppu/source/uno/prim.hxx), but what's relevant is
140 // only that it isn't a nullptr (as e.g. >>= -> uno_type_assignData ->
141 // _assignData takes a null pSource to mean "construct a default value").
146 Any::Any(Any
&& other
) {
147 detail::moveAnyInternals(other
, *this);
150 Any
& Any::operator =(Any
&& other
) {
151 uno_any_destruct(this, &cpp_release
);
152 detail::moveAnyInternals(other
, *this);
158 inline ::rtl::OUString
Any::getValueTypeName() const
160 return ::rtl::OUString( pType
->pTypeName
);
163 inline void Any::setValue( const void * pData_
, const Type
& rType
)
165 ::uno_type_any_assign(
166 this, const_cast< void * >( pData_
), rType
.getTypeLibType(),
167 cpp_acquire
, cpp_release
);
170 inline void Any::setValue( const void * pData_
, typelib_TypeDescriptionReference
* pType_
)
172 ::uno_type_any_assign(
173 this, const_cast< void * >( pData_
), pType_
,
174 cpp_acquire
, cpp_release
);
177 inline void Any::setValue( const void * pData_
, typelib_TypeDescription
* pTypeDescr
)
180 this, const_cast< void * >( pData_
), pTypeDescr
,
181 cpp_acquire
, cpp_release
);
184 inline void Any::clear()
190 inline bool Any::isExtractableTo( const Type
& rType
) const
192 return ::uno_type_isAssignableFromData(
193 rType
.getTypeLibType(), pData
, pType
,
194 cpp_queryInterface
, cpp_release
);
198 template <typename T
>
199 inline bool Any::has() const
201 Type
const & rType
= ::cppu::getTypeFavourUnsigned(static_cast< T
* >(0));
202 return ::uno_type_isAssignableFromData(
203 rType
.getTypeLibType(), pData
, pType
,
208 #if defined LIBO_INTERNAL_ONLY
209 template<> bool Any::has
<Any
>() const = delete;
212 inline bool Any::operator == ( const Any
& rAny
) const
214 return ::uno_type_equalData(
215 pData
, pType
, rAny
.pData
, rAny
.pType
,
216 cpp_queryInterface
, cpp_release
);
219 inline bool Any::operator != ( const Any
& rAny
) const
221 return (! ::uno_type_equalData(
222 pData
, pType
, rAny
.pData
, rAny
.pType
,
223 cpp_queryInterface
, cpp_release
));
228 inline Any SAL_CALL
makeAny( const C
& value
)
233 #if !defined LIBO_INTERNAL_ONLY
234 template<> Any
makeAny(sal_uInt16
const & value
)
235 { return Any(&value
, cppu::UnoType
<cppu::UnoUnsignedShortType
>::get()); }
238 template<typename T
> Any
toAny(T
const & value
) { return makeAny(value
); }
240 template<> Any
toAny(Any
const & value
) { return value
; }
242 #if defined LIBO_INTERNAL_ONLY
244 template<typename T1
, typename T2
>
245 Any
makeAny(rtl::OUStringConcat
<T1
, T2
> && value
)
246 { return Any(std::move(value
)); }
248 template<typename T1
, typename T2
>
249 Any
toAny(rtl::OUStringConcat
<T1
, T2
> && value
)
250 { return makeAny(std::move(value
)); }
252 template<typename T
> bool fromAny(Any
const & any
, T
* value
) {
253 assert(value
!= nullptr);
254 return any
>>= *value
;
257 template<> bool fromAny(Any
const & any
, Any
* value
) {
258 assert(value
!= nullptr);
266 inline void SAL_CALL
operator <<= ( Any
& rAny
, const C
& value
)
268 const Type
& rType
= ::cppu::getTypeFavourUnsigned(&value
);
269 ::uno_type_any_assign(
270 &rAny
, const_cast< C
* >( &value
), rType
.getTypeLibType(),
271 cpp_acquire
, cpp_release
);
274 // additionally for C++ bool:
277 inline void SAL_CALL
operator <<= ( Any
& rAny
, bool const & value
)
280 ::uno_type_any_assign(
281 &rAny
, &b
, cppu::UnoType
<bool>::get().getTypeLibType(),
282 cpp_acquire
, cpp_release
);
286 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
287 template< class C1
, class C2
>
288 inline void SAL_CALL
operator <<= ( Any
& rAny
, rtl::OUStringConcat
< C1
, C2
>&& value
)
290 const rtl::OUString
str( std::move(value
) );
291 const Type
& rType
= ::cppu::getTypeFavourUnsigned(&str
);
292 ::uno_type_any_assign(
293 &rAny
, const_cast< rtl::OUString
* >( &str
), rType
.getTypeLibType(),
294 cpp_acquire
, cpp_release
);
296 template<typename T1
, typename T2
>
297 void operator <<=(Any
&, rtl::OUStringConcat
<T1
, T2
> const &) = delete;
300 #if defined LIBO_INTERNAL_ONLY
301 template<> void SAL_CALL
operator <<=(Any
&, Any
const &) = delete;
305 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, C
& value
)
307 const Type
& rType
= ::cppu::getTypeFavourUnsigned(&value
);
308 return ::uno_type_assignData(
309 &value
, rType
.getTypeLibType(),
310 rAny
.pData
, rAny
.pType
,
312 cpp_acquire
, cpp_release
);
318 inline bool SAL_CALL
operator >>= ( const ::com::sun::star::uno::Any
& rAny
, sal_Bool
& value
)
320 if (typelib_TypeClass_BOOLEAN
== rAny
.pType
->eTypeClass
)
322 value
= bool(* static_cast< const sal_Bool
* >( rAny
.pData
));
329 inline bool SAL_CALL
operator == ( const Any
& rAny
, const sal_Bool
& value
)
331 return (typelib_TypeClass_BOOLEAN
== rAny
.pType
->eTypeClass
&&
332 bool(value
) == bool(* static_cast< const sal_Bool
* >( rAny
.pData
)));
337 inline bool SAL_CALL
operator >>= ( Any
const & rAny
, bool & value
)
339 if (rAny
.pType
->eTypeClass
== typelib_TypeClass_BOOLEAN
)
341 value
= *static_cast< sal_Bool
const * >( rAny
.pData
);
349 inline bool SAL_CALL
operator == ( Any
const & rAny
, bool const & value
)
351 return (rAny
.pType
->eTypeClass
== typelib_TypeClass_BOOLEAN
&&
353 bool(*static_cast< sal_Bool
const * >( rAny
.pData
))));
359 inline bool SAL_CALL
operator >>= ( const ::com::sun::star::uno::Any
& rAny
, sal_Int8
& value
)
361 if (typelib_TypeClass_BYTE
== rAny
.pType
->eTypeClass
)
363 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
371 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_Int16
& value
)
373 switch (rAny
.pType
->eTypeClass
)
375 case typelib_TypeClass_BYTE
:
376 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
378 case typelib_TypeClass_SHORT
:
379 case typelib_TypeClass_UNSIGNED_SHORT
:
380 value
= * static_cast< const sal_Int16
* >( rAny
.pData
);
388 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_uInt16
& value
)
390 switch (rAny
.pType
->eTypeClass
)
392 case typelib_TypeClass_BYTE
:
393 value
= static_cast<sal_uInt16
>( * static_cast< const sal_Int8
* >( rAny
.pData
) );
395 case typelib_TypeClass_SHORT
:
396 case typelib_TypeClass_UNSIGNED_SHORT
:
397 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
406 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_Int32
& value
)
408 switch (rAny
.pType
->eTypeClass
)
410 case typelib_TypeClass_BYTE
:
411 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
413 case typelib_TypeClass_SHORT
:
414 value
= * static_cast< const sal_Int16
* >( rAny
.pData
);
416 case typelib_TypeClass_UNSIGNED_SHORT
:
417 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
419 case typelib_TypeClass_LONG
:
420 case typelib_TypeClass_UNSIGNED_LONG
:
421 value
= * static_cast< const sal_Int32
* >( rAny
.pData
);
429 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_uInt32
& value
)
431 switch (rAny
.pType
->eTypeClass
)
433 case typelib_TypeClass_BYTE
:
434 value
= static_cast<sal_uInt32
>( * static_cast< const sal_Int8
* >( rAny
.pData
) );
436 case typelib_TypeClass_SHORT
:
437 value
= static_cast<sal_uInt32
>( * static_cast< const sal_Int16
* >( rAny
.pData
) );
439 case typelib_TypeClass_UNSIGNED_SHORT
:
440 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
442 case typelib_TypeClass_LONG
:
443 case typelib_TypeClass_UNSIGNED_LONG
:
444 value
= * static_cast< const sal_uInt32
* >( rAny
.pData
);
453 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_Int64
& value
)
455 switch (rAny
.pType
->eTypeClass
)
457 case typelib_TypeClass_BYTE
:
458 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
460 case typelib_TypeClass_SHORT
:
461 value
= * static_cast< const sal_Int16
* >( rAny
.pData
);
463 case typelib_TypeClass_UNSIGNED_SHORT
:
464 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
466 case typelib_TypeClass_LONG
:
467 value
= * static_cast< const sal_Int32
* >( rAny
.pData
);
469 case typelib_TypeClass_UNSIGNED_LONG
:
470 value
= * static_cast< const sal_uInt32
* >( rAny
.pData
);
472 case typelib_TypeClass_HYPER
:
473 case typelib_TypeClass_UNSIGNED_HYPER
:
474 value
= * static_cast< const sal_Int64
* >( rAny
.pData
);
482 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_uInt64
& value
)
484 switch (rAny
.pType
->eTypeClass
)
486 case typelib_TypeClass_BYTE
:
487 value
= static_cast<sal_uInt64
>( * static_cast< const sal_Int8
* >( rAny
.pData
) );
489 case typelib_TypeClass_SHORT
:
490 value
= static_cast<sal_uInt64
>( * static_cast< const sal_Int16
* >( rAny
.pData
) );
492 case typelib_TypeClass_UNSIGNED_SHORT
:
493 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
495 case typelib_TypeClass_LONG
:
496 value
= static_cast<sal_uInt64
>( * static_cast< const sal_Int32
* >( rAny
.pData
) );
498 case typelib_TypeClass_UNSIGNED_LONG
:
499 value
= * static_cast< const sal_uInt32
* >( rAny
.pData
);
501 case typelib_TypeClass_HYPER
:
502 case typelib_TypeClass_UNSIGNED_HYPER
:
503 value
= * static_cast< const sal_uInt64
* >( rAny
.pData
);
512 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, float & value
)
514 switch (rAny
.pType
->eTypeClass
)
516 case typelib_TypeClass_BYTE
:
517 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
519 case typelib_TypeClass_SHORT
:
520 value
= * static_cast< const sal_Int16
* >( rAny
.pData
);
522 case typelib_TypeClass_UNSIGNED_SHORT
:
523 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
525 case typelib_TypeClass_FLOAT
:
526 value
= * static_cast< const float * >( rAny
.pData
);
535 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, double & value
)
537 switch (rAny
.pType
->eTypeClass
)
539 case typelib_TypeClass_BYTE
:
540 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
542 case typelib_TypeClass_SHORT
:
543 value
= * static_cast< const sal_Int16
* >( rAny
.pData
);
545 case typelib_TypeClass_UNSIGNED_SHORT
:
546 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
548 case typelib_TypeClass_LONG
:
549 value
= * static_cast< const sal_Int32
* >( rAny
.pData
);
551 case typelib_TypeClass_UNSIGNED_LONG
:
552 value
= * static_cast< const sal_uInt32
* >( rAny
.pData
);
554 case typelib_TypeClass_FLOAT
:
555 value
= * static_cast< const float * >( rAny
.pData
);
557 case typelib_TypeClass_DOUBLE
:
558 value
= * static_cast< const double * >( rAny
.pData
);
567 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, ::rtl::OUString
& value
)
569 if (typelib_TypeClass_STRING
== rAny
.pType
->eTypeClass
)
571 value
= * static_cast< const ::rtl::OUString
* >( rAny
.pData
);
578 inline bool SAL_CALL
operator == ( const Any
& rAny
, const ::rtl::OUString
& value
)
580 return (typelib_TypeClass_STRING
== rAny
.pType
->eTypeClass
&&
581 value
== * static_cast< const ::rtl::OUString
* >( rAny
.pData
) );
586 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, Type
& value
)
588 if (typelib_TypeClass_TYPE
== rAny
.pType
->eTypeClass
)
590 value
= * static_cast< const Type
* >( rAny
.pData
);
597 inline bool SAL_CALL
operator == ( const Any
& rAny
, const Type
& value
)
599 return (typelib_TypeClass_TYPE
== rAny
.pType
->eTypeClass
&&
600 value
.equals( * static_cast< const Type
* >( rAny
.pData
) ));
604 #if defined LIBO_INTERNAL_ONLY
605 template<> bool SAL_CALL
operator >>=(Any
const &, Any
&) = delete;
608 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, Any
& value
)
612 ::uno_type_any_assign(
613 &value
, rAny
.pData
, rAny
.pType
,
614 cpp_acquire
, cpp_release
);
622 inline bool SAL_CALL
operator == ( const Any
& rAny
, const BaseReference
& value
)
624 if (typelib_TypeClass_INTERFACE
== rAny
.pType
->eTypeClass
)
626 return static_cast< const BaseReference
* >( rAny
.pData
)->operator == ( value
);
631 // operator to compare to an any.
634 inline bool SAL_CALL
operator == ( const Any
& rAny
, const C
& value
)
636 const Type
& rType
= ::cppu::getTypeFavourUnsigned(&value
);
637 return ::uno_type_equalData(
638 rAny
.pData
, rAny
.pType
,
639 const_cast< C
* >( &value
), rType
.getTypeLibType(),
640 cpp_queryInterface
, cpp_release
);
642 // operator to compare to an any. may use specialized operators ==.
645 inline bool SAL_CALL
operator != ( const Any
& rAny
, const C
& value
)
647 return (! operator == ( rAny
, value
));
650 template <typename T
>
654 if (! (*this >>= value
)) {
655 throw RuntimeException(
657 cppu_Any_extraction_failure_msg(
659 ::cppu::getTypeFavourUnsigned(&value
).getTypeLibType() ),
665 #if defined LIBO_INTERNAL_ONLY
666 template<> Any
Any::get() const = delete;
670 Support for Any in std::ostream (and thus in CPPUNIT_ASSERT or SAL_INFO
671 macros, for example).
673 @since LibreOffice 4.2
675 template<typename charT
, typename traits
>
676 inline std::basic_ostream
<charT
, traits
> &operator<<(std::basic_ostream
<charT
, traits
> &o
, Any
const &any
) {
677 o
<< "<Any: (" << any
.getValueTypeName() << ')';
678 switch(any
.pType
->eTypeClass
) {
679 case typelib_TypeClass_VOID
:
681 case typelib_TypeClass_BOOLEAN
:
682 o
<< ' ' << any
.get
<bool>();
684 case typelib_TypeClass_BYTE
:
685 case typelib_TypeClass_SHORT
:
686 case typelib_TypeClass_LONG
:
687 case typelib_TypeClass_HYPER
:
688 o
<< ' ' << any
.get
<sal_Int64
>();
690 case typelib_TypeClass_UNSIGNED_SHORT
:
691 case typelib_TypeClass_UNSIGNED_LONG
:
692 case typelib_TypeClass_UNSIGNED_HYPER
:
693 o
<< ' ' << any
.get
<sal_uInt64
>();
695 case typelib_TypeClass_FLOAT
:
696 case typelib_TypeClass_DOUBLE
:
697 o
<< ' ' << any
.get
<double>();
699 case typelib_TypeClass_CHAR
: {
700 std::ios_base::fmtflags flgs
= o
.setf(
701 std::ios_base::hex
, std::ios_base::basefield
);
702 charT fill
= o
.fill('0');
703 o
<< " U+" << std::setw(4)
704 << *static_cast<sal_Unicode
const *>(any
.getValue());
709 case typelib_TypeClass_STRING
:
710 o
<< ' ' << any
.get
<rtl::OUString
>();
712 case typelib_TypeClass_TYPE
:
713 o
<< ' ' << any
.get
<css::uno::Type
>().getTypeName();
715 case typelib_TypeClass_SEQUENCE
:
717 << ((*static_cast<uno_Sequence
* const *>(any
.getValue()))->
720 case typelib_TypeClass_ENUM
:
721 o
<< ' ' << *static_cast<sal_Int32
const *>(any
.getValue());
723 case typelib_TypeClass_STRUCT
:
724 case typelib_TypeClass_EXCEPTION
:
725 o
<< ' ' << any
.getValue();
727 case typelib_TypeClass_INTERFACE
:
728 o
<< ' ' << *static_cast<void * const *>(any
.getValue());
731 assert(false); // this cannot happen
745 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */