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 .
21 * This file is part of LibreOffice published API.
23 #ifndef INCLUDED_COM_SUN_STAR_UNO_ANY_HXX
24 #define INCLUDED_COM_SUN_STAR_UNO_ANY_HXX
26 #include "sal/config.h"
35 #include "com/sun/star/uno/Any.h"
37 #include "uno/sequence2.h"
38 #include "com/sun/star/uno/Type.hxx"
39 #include "com/sun/star/uno/Reference.h"
40 #include "com/sun/star/uno/genfunc.hxx"
41 #include "com/sun/star/uno/RuntimeException.hpp"
42 #include "cppu/cppudllapi.h"
43 #include "cppu/unotype.hxx"
45 extern "C" CPPU_DLLPUBLIC rtl_uString
* SAL_CALL
cppu_Any_extraction_failure_msg(
46 uno_Any
const * pAny
, typelib_TypeDescriptionReference
* pType
)
61 ::uno_any_construct( this, NULL
, NULL
, cpp_acquire
);
66 inline Any::Any( T
const & value
)
68 ::uno_type_any_construct(
69 this, const_cast<T
*>(&value
),
70 ::cppu::getTypeFavourUnsigned(&value
).getTypeLibType(),
74 inline Any::Any( bool value
)
77 ::uno_type_any_construct(
78 this, &b
, cppu::UnoType
<bool>::get().getTypeLibType(),
82 #if defined LIBO_INTERNAL_ONLY
83 template<typename T1
, typename T2
>
84 Any::Any(rtl::OUStringConcat
<T1
, T2
> && value
):
85 Any(rtl::OUString(std::move(value
)))
87 template<std::size_t nBufSize
>
88 Any::Any(rtl::StringNumber
<sal_Unicode
, nBufSize
> && value
): Any(rtl::OUString(std::move(value
))) {}
89 template <std::size_t N
>
90 Any::Any(const rtl::OUStringLiteral
<N
>& value
): Any(rtl::OUString(value
)) {}
93 inline Any::Any( const Any
& rAny
)
95 ::uno_type_any_construct( this, rAny
.pData
, rAny
.pType
, cpp_acquire
);
98 inline Any::Any( const void * pData_
, const Type
& rType
)
100 ::uno_type_any_construct(
101 this, const_cast< void * >( pData_
), rType
.getTypeLibType(),
105 inline Any::Any( const void * pData_
, typelib_TypeDescription
* pTypeDescr
)
108 this, const_cast< void * >( pData_
), pTypeDescr
, cpp_acquire
);
111 inline Any::Any( const void * pData_
, typelib_TypeDescriptionReference
* pType_
)
113 ::uno_type_any_construct(
114 this, const_cast< void * >( pData_
), pType_
, cpp_acquire
);
123 inline Any
& Any::operator = ( const Any
& rAny
)
127 ::uno_type_any_assign(
128 this, rAny
.pData
, rAny
.pType
,
129 cpp_acquire
, cpp_release
);
134 #if defined LIBO_INTERNAL_ONLY
136 #if !defined(__COVERITY__) // suppress COPY_INSTEAD_OF_MOVE suggestions
137 Any::Any(Any
&& other
) noexcept
{
138 uno_any_construct(this, nullptr, nullptr, &cpp_acquire
);
139 std::swap(other
.pType
, pType
);
140 std::swap(other
.pData
, pData
);
141 std::swap(other
.pReserved
, pReserved
);
142 if (pData
== &other
.pReserved
) {
145 // This leaves other.pData (where "other" is now VOID) dangling to somewhere (cf.
146 // CONSTRUCT_EMPTY_ANY, cppu/source/uno/prim.hxx), but what's relevant is
147 // only that it isn't a nullptr (as e.g. >>= -> uno_type_assignData ->
148 // _assignData takes a null pSource to mean "construct a default value").
152 Any
& Any::operator =(Any
&& other
) noexcept
{
153 std::swap(other
.pType
, pType
);
154 std::swap(other
.pData
, pData
);
155 std::swap(other
.pReserved
, pReserved
);
156 if (pData
== &other
.pReserved
) {
159 if (other
.pData
== &pReserved
) {
160 other
.pData
= &other
.pReserved
;
167 inline ::rtl::OUString
Any::getValueTypeName() const
169 return ::rtl::OUString( pType
->pTypeName
);
172 inline void Any::setValue( const void * pData_
, const Type
& rType
)
174 ::uno_type_any_assign(
175 this, const_cast< void * >( pData_
), rType
.getTypeLibType(),
176 cpp_acquire
, cpp_release
);
179 inline void Any::setValue( const void * pData_
, typelib_TypeDescriptionReference
* pType_
)
181 ::uno_type_any_assign(
182 this, const_cast< void * >( pData_
), pType_
,
183 cpp_acquire
, cpp_release
);
186 inline void Any::setValue( const void * pData_
, typelib_TypeDescription
* pTypeDescr
)
189 this, const_cast< void * >( pData_
), pTypeDescr
,
190 cpp_acquire
, cpp_release
);
193 inline void Any::clear()
199 inline bool Any::isExtractableTo( const Type
& rType
) const
201 return ::uno_type_isAssignableFromData(
202 rType
.getTypeLibType(), pData
, pType
,
203 cpp_queryInterface
, cpp_release
);
207 template <typename T
>
208 inline bool Any::has() const
210 Type
const & rType
= ::cppu::getTypeFavourUnsigned(static_cast< T
* >(NULL
));
211 return ::uno_type_isAssignableFromData(
212 rType
.getTypeLibType(), pData
, pType
,
217 #if defined LIBO_INTERNAL_ONLY
218 template<> bool Any::has
<Any
>() const = delete;
221 inline bool Any::operator == ( const Any
& rAny
) const
223 return ::uno_type_equalData(
224 pData
, pType
, rAny
.pData
, rAny
.pType
,
225 cpp_queryInterface
, cpp_release
);
228 inline bool Any::operator != ( const Any
& rAny
) const
230 return (! ::uno_type_equalData(
231 pData
, pType
, rAny
.pData
, rAny
.pType
,
232 cpp_queryInterface
, cpp_release
));
236 #if !defined LIBO_INTERNAL_ONLY
238 inline Any SAL_CALL
makeAny( const C
& value
)
243 template<> Any
makeAny(sal_uInt16
const & value
)
244 { return Any(&value
, cppu::UnoType
<cppu::UnoUnsignedShortType
>::get()); }
247 template<typename T
> Any
toAny(T
const & value
) {
251 template<> Any
toAny(Any
const & value
) { return value
; }
253 #if defined LIBO_INTERNAL_ONLY
255 inline Any
toAny(Any
&& value
) { return std::move(value
); }
257 template<typename T1
, typename T2
>
258 Any
toAny(rtl::OUStringConcat
<T1
, T2
> && value
)
259 { return Any(std::move(value
)); }
261 template<std::size_t nBufSize
>
262 Any
toAny(rtl::StringNumber
<sal_Unicode
, nBufSize
> && value
)
263 { return Any(std::move(value
)); }
265 template<typename T
> bool fromAny(Any
const & any
, T
* value
) {
266 assert(value
!= nullptr);
267 return any
>>= *value
;
270 template<> bool fromAny(Any
const & any
, Any
* value
) {
271 assert(value
!= nullptr);
279 inline void SAL_CALL
operator <<= ( Any
& rAny
, const C
& value
)
281 const Type
& rType
= ::cppu::getTypeFavourUnsigned(&value
);
282 ::uno_type_any_assign(
283 &rAny
, const_cast< C
* >( &value
), rType
.getTypeLibType(),
284 cpp_acquire
, cpp_release
);
287 // additionally for C++ bool:
290 inline void SAL_CALL
operator <<= ( Any
& rAny
, bool const & value
)
293 ::uno_type_any_assign(
294 &rAny
, &b
, cppu::UnoType
<bool>::get().getTypeLibType(),
295 cpp_acquire
, cpp_release
);
299 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
300 template< class C1
, class C2
>
301 inline void operator <<= ( Any
& rAny
, rtl::OUStringConcat
< C1
, C2
>&& value
)
303 const rtl::OUString
str( std::move(value
) );
304 const Type
& rType
= ::cppu::getTypeFavourUnsigned(&str
);
305 ::uno_type_any_assign(
306 &rAny
, const_cast< rtl::OUString
* >( &str
), rType
.getTypeLibType(),
307 cpp_acquire
, cpp_release
);
309 template<typename T1
, typename T2
>
310 void operator <<=(Any
&, rtl::OUStringConcat
<T1
, T2
> const &) = delete;
311 template< std::size_t nBufSize
>
312 inline void operator <<= ( Any
& rAny
, rtl::StringNumber
< sal_Unicode
, nBufSize
>&& value
)
314 const rtl::OUString
str( std::move(value
) );
315 const Type
& rType
= ::cppu::getTypeFavourUnsigned(&str
);
316 ::uno_type_any_assign(
317 &rAny
, const_cast< rtl::OUString
* >( &str
), rType
.getTypeLibType(),
318 cpp_acquire
, cpp_release
);
320 template<std::size_t nBufSize
>
321 void operator <<=(Any
&, rtl::StringNumber
<sal_Unicode
, nBufSize
> const &) = delete;
324 #if defined LIBO_INTERNAL_ONLY
325 template<> void SAL_CALL
operator <<=(Any
&, Any
const &) = delete;
329 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, C
& value
)
331 const Type
& rType
= ::cppu::getTypeFavourUnsigned(&value
);
332 return ::uno_type_assignData(
333 &value
, rType
.getTypeLibType(),
334 rAny
.pData
, rAny
.pType
,
336 cpp_acquire
, cpp_release
);
342 inline bool SAL_CALL
operator >>= ( const ::com::sun::star::uno::Any
& rAny
, sal_Bool
& value
)
344 if (typelib_TypeClass_BOOLEAN
== rAny
.pType
->eTypeClass
)
346 value
= bool(* static_cast< const sal_Bool
* >( rAny
.pData
));
353 inline bool SAL_CALL
operator == ( const Any
& rAny
, const sal_Bool
& value
)
355 return (typelib_TypeClass_BOOLEAN
== rAny
.pType
->eTypeClass
&&
356 bool(value
) == bool(* static_cast< const sal_Bool
* >( rAny
.pData
)));
361 inline bool SAL_CALL
operator >>= ( Any
const & rAny
, bool & value
)
363 if (rAny
.pType
->eTypeClass
== typelib_TypeClass_BOOLEAN
)
365 value
= *static_cast< sal_Bool
const * >( rAny
.pData
);
373 inline bool SAL_CALL
operator == ( Any
const & rAny
, bool const & value
)
375 return (rAny
.pType
->eTypeClass
== typelib_TypeClass_BOOLEAN
&&
377 bool(*static_cast< sal_Bool
const * >( rAny
.pData
))));
383 inline bool SAL_CALL
operator >>= ( const ::com::sun::star::uno::Any
& rAny
, sal_Int8
& value
)
385 if (typelib_TypeClass_BYTE
== rAny
.pType
->eTypeClass
)
387 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
395 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_Int16
& value
)
397 switch (rAny
.pType
->eTypeClass
)
399 case typelib_TypeClass_BYTE
:
400 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
402 case typelib_TypeClass_SHORT
:
403 case typelib_TypeClass_UNSIGNED_SHORT
:
404 value
= * static_cast< const sal_Int16
* >( rAny
.pData
);
412 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_uInt16
& value
)
414 switch (rAny
.pType
->eTypeClass
)
416 case typelib_TypeClass_BYTE
:
417 value
= static_cast<sal_uInt16
>( * static_cast< const sal_Int8
* >( rAny
.pData
) );
419 case typelib_TypeClass_SHORT
:
420 case typelib_TypeClass_UNSIGNED_SHORT
:
421 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
430 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_Int32
& value
)
432 switch (rAny
.pType
->eTypeClass
)
434 case typelib_TypeClass_BYTE
:
435 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
437 case typelib_TypeClass_SHORT
:
438 value
= * static_cast< const sal_Int16
* >( rAny
.pData
);
440 case typelib_TypeClass_UNSIGNED_SHORT
:
441 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
443 case typelib_TypeClass_LONG
:
444 case typelib_TypeClass_UNSIGNED_LONG
:
445 value
= * static_cast< const sal_Int32
* >( rAny
.pData
);
453 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_uInt32
& value
)
455 switch (rAny
.pType
->eTypeClass
)
457 case typelib_TypeClass_BYTE
:
458 value
= static_cast<sal_uInt32
>( * static_cast< const sal_Int8
* >( rAny
.pData
) );
460 case typelib_TypeClass_SHORT
:
461 value
= static_cast<sal_uInt32
>( * 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 case typelib_TypeClass_UNSIGNED_LONG
:
468 value
= * static_cast< const sal_uInt32
* >( rAny
.pData
);
477 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_Int64
& value
)
479 switch (rAny
.pType
->eTypeClass
)
481 case typelib_TypeClass_BYTE
:
482 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
484 case typelib_TypeClass_SHORT
:
485 value
= * static_cast< const sal_Int16
* >( rAny
.pData
);
487 case typelib_TypeClass_UNSIGNED_SHORT
:
488 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
490 case typelib_TypeClass_LONG
:
491 value
= * static_cast< const sal_Int32
* >( rAny
.pData
);
493 case typelib_TypeClass_UNSIGNED_LONG
:
494 value
= * static_cast< const sal_uInt32
* >( rAny
.pData
);
496 case typelib_TypeClass_HYPER
:
497 case typelib_TypeClass_UNSIGNED_HYPER
:
498 value
= * static_cast< const sal_Int64
* >( rAny
.pData
);
506 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, sal_uInt64
& value
)
508 switch (rAny
.pType
->eTypeClass
)
510 case typelib_TypeClass_BYTE
:
511 value
= static_cast<sal_uInt64
>( * static_cast< const sal_Int8
* >( rAny
.pData
) );
513 case typelib_TypeClass_SHORT
:
514 value
= static_cast<sal_uInt64
>( * static_cast< const sal_Int16
* >( rAny
.pData
) );
516 case typelib_TypeClass_UNSIGNED_SHORT
:
517 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
519 case typelib_TypeClass_LONG
:
520 value
= static_cast<sal_uInt64
>( * static_cast< const sal_Int32
* >( rAny
.pData
) );
522 case typelib_TypeClass_UNSIGNED_LONG
:
523 value
= * static_cast< const sal_uInt32
* >( rAny
.pData
);
525 case typelib_TypeClass_HYPER
:
526 case typelib_TypeClass_UNSIGNED_HYPER
:
527 value
= * static_cast< const sal_uInt64
* >( rAny
.pData
);
536 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, float & value
)
538 switch (rAny
.pType
->eTypeClass
)
540 case typelib_TypeClass_BYTE
:
541 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
543 case typelib_TypeClass_SHORT
:
544 value
= * static_cast< const sal_Int16
* >( rAny
.pData
);
546 case typelib_TypeClass_UNSIGNED_SHORT
:
547 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
549 case typelib_TypeClass_FLOAT
:
550 value
= * static_cast< const float * >( rAny
.pData
);
559 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, double & value
)
561 switch (rAny
.pType
->eTypeClass
)
563 case typelib_TypeClass_BYTE
:
564 value
= * static_cast< const sal_Int8
* >( rAny
.pData
);
566 case typelib_TypeClass_SHORT
:
567 value
= * static_cast< const sal_Int16
* >( rAny
.pData
);
569 case typelib_TypeClass_UNSIGNED_SHORT
:
570 value
= * static_cast< const sal_uInt16
* >( rAny
.pData
);
572 case typelib_TypeClass_LONG
:
573 value
= * static_cast< const sal_Int32
* >( rAny
.pData
);
575 case typelib_TypeClass_UNSIGNED_LONG
:
576 value
= * static_cast< const sal_uInt32
* >( rAny
.pData
);
578 case typelib_TypeClass_FLOAT
:
579 value
= * static_cast< const float * >( rAny
.pData
);
581 case typelib_TypeClass_DOUBLE
:
582 value
= * static_cast< const double * >( rAny
.pData
);
591 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, ::rtl::OUString
& value
)
593 if (typelib_TypeClass_STRING
== rAny
.pType
->eTypeClass
)
595 value
= * static_cast< const ::rtl::OUString
* >( rAny
.pData
);
602 inline bool SAL_CALL
operator == ( const Any
& rAny
, const ::rtl::OUString
& value
)
604 return (typelib_TypeClass_STRING
== rAny
.pType
->eTypeClass
&&
605 value
== * static_cast< const ::rtl::OUString
* >( rAny
.pData
) );
608 #if defined LIBO_INTERNAL_ONLY
609 template<std::size_t N
>
610 inline bool SAL_CALL
operator == (const Any
& rAny
, const rtl::OUStringLiteral
<N
>& value
)
612 return operator ==(rAny
, rtl::OUString(value
));
618 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, Type
& value
)
620 if (typelib_TypeClass_TYPE
== rAny
.pType
->eTypeClass
)
622 value
= * static_cast< const Type
* >( rAny
.pData
);
629 inline bool SAL_CALL
operator == ( const Any
& rAny
, const Type
& value
)
631 return (typelib_TypeClass_TYPE
== rAny
.pType
->eTypeClass
&&
632 value
.equals( * static_cast< const Type
* >( rAny
.pData
) ));
636 #if defined LIBO_INTERNAL_ONLY
637 template<> bool SAL_CALL
operator >>=(Any
const &, Any
&) = delete;
640 inline bool SAL_CALL
operator >>= ( const Any
& rAny
, Any
& value
)
644 ::uno_type_any_assign(
645 &value
, rAny
.pData
, rAny
.pType
,
646 cpp_acquire
, cpp_release
);
654 inline bool SAL_CALL
operator == ( const Any
& rAny
, const BaseReference
& value
)
656 if (typelib_TypeClass_INTERFACE
== rAny
.pType
->eTypeClass
)
658 return static_cast< const BaseReference
* >( rAny
.pData
)->operator == ( value
);
663 // operator to compare to an any.
666 inline bool SAL_CALL
operator == ( const Any
& rAny
, const C
& value
)
668 const Type
& rType
= ::cppu::getTypeFavourUnsigned(&value
);
669 return ::uno_type_equalData(
670 rAny
.pData
, rAny
.pType
,
671 const_cast< C
* >( &value
), rType
.getTypeLibType(),
672 cpp_queryInterface
, cpp_release
);
674 // operator to compare to an any. may use specialized operators ==.
677 inline bool SAL_CALL
operator != ( const Any
& rAny
, const C
& value
)
679 return (! operator == ( rAny
, value
));
682 template <typename T
>
686 if (! (*this >>= value
)) {
687 throw RuntimeException(
689 cppu_Any_extraction_failure_msg(
691 ::cppu::getTypeFavourUnsigned(&value
).getTypeLibType() ),
697 #if defined LIBO_INTERNAL_ONLY
698 template<> Any
Any::get() const = delete;
702 Support for Any in std::ostream (and thus in CPPUNIT_ASSERT or SAL_INFO
703 macros, for example).
705 @since LibreOffice 4.2
707 template<typename charT
, typename traits
>
708 inline std::basic_ostream
<charT
, traits
> &operator<<(std::basic_ostream
<charT
, traits
> &o
, Any
const &any
) {
709 o
<< "<Any: (" << any
.getValueTypeName() << ')';
710 switch(any
.pType
->eTypeClass
) {
711 case typelib_TypeClass_VOID
:
713 case typelib_TypeClass_BOOLEAN
:
714 o
<< ' ' << any
.get
<bool>();
716 case typelib_TypeClass_BYTE
:
717 case typelib_TypeClass_SHORT
:
718 case typelib_TypeClass_LONG
:
719 case typelib_TypeClass_HYPER
:
720 o
<< ' ' << any
.get
<sal_Int64
>();
722 case typelib_TypeClass_UNSIGNED_SHORT
:
723 case typelib_TypeClass_UNSIGNED_LONG
:
724 case typelib_TypeClass_UNSIGNED_HYPER
:
725 o
<< ' ' << any
.get
<sal_uInt64
>();
727 case typelib_TypeClass_FLOAT
:
728 case typelib_TypeClass_DOUBLE
:
729 o
<< ' ' << any
.get
<double>();
731 case typelib_TypeClass_CHAR
: {
732 std::ios_base::fmtflags flgs
= o
.setf(
733 std::ios_base::hex
, std::ios_base::basefield
);
734 charT fill
= o
.fill('0');
735 o
<< " U+" << std::setw(4)
736 << unsigned(*static_cast<sal_Unicode
const *>(any
.getValue()));
741 case typelib_TypeClass_STRING
:
742 o
<< ' ' << any
.get
<rtl::OUString
>();
744 case typelib_TypeClass_TYPE
:
745 o
<< ' ' << any
.get
<css::uno::Type
>().getTypeName();
747 case typelib_TypeClass_SEQUENCE
:
749 << ((*static_cast<uno_Sequence
* const *>(any
.getValue()))->
752 case typelib_TypeClass_ENUM
:
753 o
<< ' ' << *static_cast<sal_Int32
const *>(any
.getValue());
755 case typelib_TypeClass_STRUCT
:
756 case typelib_TypeClass_EXCEPTION
:
757 o
<< ' ' << any
.getValue();
759 case typelib_TypeClass_INTERFACE
:
760 o
<< ' ' << *static_cast<void * const *>(any
.getValue());
763 assert(false); // this cannot happen
777 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */