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
) noexcept
{
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
) noexcept
{
147 detail::moveAnyInternals(other
, *this);
150 Any
& Any::operator =(Any
&& other
) noexcept
{
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
)); }
253 Any
makeAny(rtl::OUStringNumber
<T
> && value
)
254 { return Any(OUString(std::move(value
))); }
257 Any
toAny(rtl::OUStringNumber
<T
> && value
)
258 { return makeAny(std::move(value
)); }
260 template<typename T
> bool fromAny(Any
const & any
, T
* value
) {
261 assert(value
!= nullptr);
262 return any
>>= *value
;
265 template<> bool fromAny(Any
const & any
, Any
* value
) {
266 assert(value
!= nullptr);
274 inline void SAL_CALL
operator <<= ( Any
& rAny
, const C
& value
)
276 const Type
& rType
= ::cppu::getTypeFavourUnsigned(&value
);
277 ::uno_type_any_assign(
278 &rAny
, const_cast< C
* >( &value
), rType
.getTypeLibType(),
279 cpp_acquire
, cpp_release
);
282 // additionally for C++ bool:
285 inline void SAL_CALL
operator <<= ( Any
& rAny
, bool const & value
)
288 ::uno_type_any_assign(
289 &rAny
, &b
, cppu::UnoType
<bool>::get().getTypeLibType(),
290 cpp_acquire
, cpp_release
);
294 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
295 template< class C1
, class C2
>
296 inline void SAL_CALL
operator <<= ( Any
& rAny
, rtl::OUStringConcat
< C1
, C2
>&& value
)
298 const rtl::OUString
str( std::move(value
) );
299 const Type
& rType
= ::cppu::getTypeFavourUnsigned(&str
);
300 ::uno_type_any_assign(
301 &rAny
, const_cast< rtl::OUString
* >( &str
), rType
.getTypeLibType(),
302 cpp_acquire
, cpp_release
);
304 template<typename T1
, typename T2
>
305 void operator <<=(Any
&, rtl::OUStringConcat
<T1
, T2
> const &) = delete;
307 inline void SAL_CALL
operator <<= ( Any
& rAny
, rtl::OUStringNumber
< C
>&& value
)
309 const rtl::OUString
str( std::move(value
) );
310 const Type
& rType
= ::cppu::getTypeFavourUnsigned(&str
);
311 ::uno_type_any_assign(
312 &rAny
, const_cast< rtl::OUString
* >( &str
), rType
.getTypeLibType(),
313 cpp_acquire
, cpp_release
);
316 void operator <<=(Any
&, rtl::OUStringNumber
<T
> const &) = delete;
319 #if defined LIBO_INTERNAL_ONLY
320 template<> void SAL_CALL
operator <<=(Any
&, Any
const &) = delete;
324 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, C
& value
)
326 const Type
& rType
= ::cppu::getTypeFavourUnsigned(&value
);
327 return ::uno_type_assignData(
328 &value
, rType
.getTypeLibType(),
329 rAny
.pData
, rAny
.pType
,
331 cpp_acquire
, cpp_release
);
337 inline bool SAL_CALL
operator >>= ( const ::com::sun::star::uno::Any
& rAny
, sal_Bool
& value
)
339 if (typelib_TypeClass_BOOLEAN
== rAny
.pType
->eTypeClass
)
341 value
= bool(* static_cast< const sal_Bool
* >( rAny
.pData
));
348 inline bool SAL_CALL
operator == ( const Any
& rAny
, const sal_Bool
& value
)
350 return (typelib_TypeClass_BOOLEAN
== rAny
.pType
->eTypeClass
&&
351 bool(value
) == bool(* static_cast< const sal_Bool
* >( rAny
.pData
)));
356 inline bool SAL_CALL
operator >>= ( Any
const & rAny
, bool & value
)
358 if (rAny
.pType
->eTypeClass
== typelib_TypeClass_BOOLEAN
)
360 value
= *static_cast< sal_Bool
const * >( rAny
.pData
);
368 inline bool SAL_CALL
operator == ( Any
const & rAny
, bool const & value
)
370 return (rAny
.pType
->eTypeClass
== typelib_TypeClass_BOOLEAN
&&
372 bool(*static_cast< sal_Bool
const * >( rAny
.pData
))));
378 inline bool SAL_CALL
operator >>= ( const ::com::sun::star::uno::Any
& rAny
, sal_Int8
& value
)
380 if (typelib_TypeClass_BYTE
== rAny
.pType
->eTypeClass
)
382 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
390 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_Int16
& value
)
392 switch (rAny
.pType
->eTypeClass
)
394 case typelib_TypeClass_BYTE
:
395 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
397 case typelib_TypeClass_SHORT
:
398 case typelib_TypeClass_UNSIGNED_SHORT
:
399 value
= * static_cast< const sal_Int16
* >( rAny
.pData
);
407 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_uInt16
& value
)
409 switch (rAny
.pType
->eTypeClass
)
411 case typelib_TypeClass_BYTE
:
412 value
= static_cast<sal_uInt16
>( * static_cast< const sal_Int8
* >( rAny
.pData
) );
414 case typelib_TypeClass_SHORT
:
415 case typelib_TypeClass_UNSIGNED_SHORT
:
416 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
425 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_Int32
& value
)
427 switch (rAny
.pType
->eTypeClass
)
429 case typelib_TypeClass_BYTE
:
430 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
432 case typelib_TypeClass_SHORT
:
433 value
= * static_cast< const sal_Int16
* >( rAny
.pData
);
435 case typelib_TypeClass_UNSIGNED_SHORT
:
436 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
438 case typelib_TypeClass_LONG
:
439 case typelib_TypeClass_UNSIGNED_LONG
:
440 value
= * static_cast< const sal_Int32
* >( rAny
.pData
);
448 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_uInt32
& value
)
450 switch (rAny
.pType
->eTypeClass
)
452 case typelib_TypeClass_BYTE
:
453 value
= static_cast<sal_uInt32
>( * static_cast< const sal_Int8
* >( rAny
.pData
) );
455 case typelib_TypeClass_SHORT
:
456 value
= static_cast<sal_uInt32
>( * static_cast< const sal_Int16
* >( rAny
.pData
) );
458 case typelib_TypeClass_UNSIGNED_SHORT
:
459 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
461 case typelib_TypeClass_LONG
:
462 case typelib_TypeClass_UNSIGNED_LONG
:
463 value
= * static_cast< const sal_uInt32
* >( rAny
.pData
);
472 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_Int64
& value
)
474 switch (rAny
.pType
->eTypeClass
)
476 case typelib_TypeClass_BYTE
:
477 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
479 case typelib_TypeClass_SHORT
:
480 value
= * static_cast< const sal_Int16
* >( rAny
.pData
);
482 case typelib_TypeClass_UNSIGNED_SHORT
:
483 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
485 case typelib_TypeClass_LONG
:
486 value
= * static_cast< const sal_Int32
* >( rAny
.pData
);
488 case typelib_TypeClass_UNSIGNED_LONG
:
489 value
= * static_cast< const sal_uInt32
* >( rAny
.pData
);
491 case typelib_TypeClass_HYPER
:
492 case typelib_TypeClass_UNSIGNED_HYPER
:
493 value
= * static_cast< const sal_Int64
* >( rAny
.pData
);
501 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_uInt64
& value
)
503 switch (rAny
.pType
->eTypeClass
)
505 case typelib_TypeClass_BYTE
:
506 value
= static_cast<sal_uInt64
>( * static_cast< const sal_Int8
* >( rAny
.pData
) );
508 case typelib_TypeClass_SHORT
:
509 value
= static_cast<sal_uInt64
>( * static_cast< const sal_Int16
* >( rAny
.pData
) );
511 case typelib_TypeClass_UNSIGNED_SHORT
:
512 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
514 case typelib_TypeClass_LONG
:
515 value
= static_cast<sal_uInt64
>( * static_cast< const sal_Int32
* >( rAny
.pData
) );
517 case typelib_TypeClass_UNSIGNED_LONG
:
518 value
= * static_cast< const sal_uInt32
* >( rAny
.pData
);
520 case typelib_TypeClass_HYPER
:
521 case typelib_TypeClass_UNSIGNED_HYPER
:
522 value
= * static_cast< const sal_uInt64
* >( rAny
.pData
);
531 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, float & value
)
533 switch (rAny
.pType
->eTypeClass
)
535 case typelib_TypeClass_BYTE
:
536 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
538 case typelib_TypeClass_SHORT
:
539 value
= * static_cast< const sal_Int16
* >( rAny
.pData
);
541 case typelib_TypeClass_UNSIGNED_SHORT
:
542 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
544 case typelib_TypeClass_FLOAT
:
545 value
= * static_cast< const float * >( rAny
.pData
);
554 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, double & value
)
556 switch (rAny
.pType
->eTypeClass
)
558 case typelib_TypeClass_BYTE
:
559 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
561 case typelib_TypeClass_SHORT
:
562 value
= * static_cast< const sal_Int16
* >( rAny
.pData
);
564 case typelib_TypeClass_UNSIGNED_SHORT
:
565 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
567 case typelib_TypeClass_LONG
:
568 value
= * static_cast< const sal_Int32
* >( rAny
.pData
);
570 case typelib_TypeClass_UNSIGNED_LONG
:
571 value
= * static_cast< const sal_uInt32
* >( rAny
.pData
);
573 case typelib_TypeClass_FLOAT
:
574 value
= * static_cast< const float * >( rAny
.pData
);
576 case typelib_TypeClass_DOUBLE
:
577 value
= * static_cast< const double * >( rAny
.pData
);
586 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, ::rtl::OUString
& value
)
588 if (typelib_TypeClass_STRING
== rAny
.pType
->eTypeClass
)
590 value
= * static_cast< const ::rtl::OUString
* >( rAny
.pData
);
597 inline bool SAL_CALL
operator == ( const Any
& rAny
, const ::rtl::OUString
& value
)
599 return (typelib_TypeClass_STRING
== rAny
.pType
->eTypeClass
&&
600 value
== * static_cast< const ::rtl::OUString
* >( rAny
.pData
) );
605 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, Type
& value
)
607 if (typelib_TypeClass_TYPE
== rAny
.pType
->eTypeClass
)
609 value
= * static_cast< const Type
* >( rAny
.pData
);
616 inline bool SAL_CALL
operator == ( const Any
& rAny
, const Type
& value
)
618 return (typelib_TypeClass_TYPE
== rAny
.pType
->eTypeClass
&&
619 value
.equals( * static_cast< const Type
* >( rAny
.pData
) ));
623 #if defined LIBO_INTERNAL_ONLY
624 template<> bool SAL_CALL
operator >>=(Any
const &, Any
&) = delete;
627 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, Any
& value
)
631 ::uno_type_any_assign(
632 &value
, rAny
.pData
, rAny
.pType
,
633 cpp_acquire
, cpp_release
);
641 inline bool SAL_CALL
operator == ( const Any
& rAny
, const BaseReference
& value
)
643 if (typelib_TypeClass_INTERFACE
== rAny
.pType
->eTypeClass
)
645 return static_cast< const BaseReference
* >( rAny
.pData
)->operator == ( value
);
650 // operator to compare to an any.
653 inline bool SAL_CALL
operator == ( const Any
& rAny
, const C
& value
)
655 const Type
& rType
= ::cppu::getTypeFavourUnsigned(&value
);
656 return ::uno_type_equalData(
657 rAny
.pData
, rAny
.pType
,
658 const_cast< C
* >( &value
), rType
.getTypeLibType(),
659 cpp_queryInterface
, cpp_release
);
661 // operator to compare to an any. may use specialized operators ==.
664 inline bool SAL_CALL
operator != ( const Any
& rAny
, const C
& value
)
666 return (! operator == ( rAny
, value
));
669 template <typename T
>
673 if (! (*this >>= value
)) {
674 throw RuntimeException(
676 cppu_Any_extraction_failure_msg(
678 ::cppu::getTypeFavourUnsigned(&value
).getTypeLibType() ),
684 #if defined LIBO_INTERNAL_ONLY
685 template<> Any
Any::get() const = delete;
689 Support for Any in std::ostream (and thus in CPPUNIT_ASSERT or SAL_INFO
690 macros, for example).
692 @since LibreOffice 4.2
694 template<typename charT
, typename traits
>
695 inline std::basic_ostream
<charT
, traits
> &operator<<(std::basic_ostream
<charT
, traits
> &o
, Any
const &any
) {
696 o
<< "<Any: (" << any
.getValueTypeName() << ')';
697 switch(any
.pType
->eTypeClass
) {
698 case typelib_TypeClass_VOID
:
700 case typelib_TypeClass_BOOLEAN
:
701 o
<< ' ' << any
.get
<bool>();
703 case typelib_TypeClass_BYTE
:
704 case typelib_TypeClass_SHORT
:
705 case typelib_TypeClass_LONG
:
706 case typelib_TypeClass_HYPER
:
707 o
<< ' ' << any
.get
<sal_Int64
>();
709 case typelib_TypeClass_UNSIGNED_SHORT
:
710 case typelib_TypeClass_UNSIGNED_LONG
:
711 case typelib_TypeClass_UNSIGNED_HYPER
:
712 o
<< ' ' << any
.get
<sal_uInt64
>();
714 case typelib_TypeClass_FLOAT
:
715 case typelib_TypeClass_DOUBLE
:
716 o
<< ' ' << any
.get
<double>();
718 case typelib_TypeClass_CHAR
: {
719 std::ios_base::fmtflags flgs
= o
.setf(
720 std::ios_base::hex
, std::ios_base::basefield
);
721 charT fill
= o
.fill('0');
722 o
<< " U+" << std::setw(4)
723 << unsigned(*static_cast<sal_Unicode
const *>(any
.getValue()));
728 case typelib_TypeClass_STRING
:
729 o
<< ' ' << any
.get
<rtl::OUString
>();
731 case typelib_TypeClass_TYPE
:
732 o
<< ' ' << any
.get
<css::uno::Type
>().getTypeName();
734 case typelib_TypeClass_SEQUENCE
:
736 << ((*static_cast<uno_Sequence
* const *>(any
.getValue()))->
739 case typelib_TypeClass_ENUM
:
740 o
<< ' ' << *static_cast<sal_Int32
const *>(any
.getValue());
742 case typelib_TypeClass_STRUCT
:
743 case typelib_TypeClass_EXCEPTION
:
744 o
<< ' ' << any
.getValue();
746 case typelib_TypeClass_INTERFACE
:
747 o
<< ' ' << *static_cast<void * const *>(any
.getValue());
750 assert(false); // this cannot happen
764 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */