/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project .
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2 . 0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/.
*/
#ifndef INCLUDED_O3TL_ANY_HXX
#define INCLUDED_O3TL_ANY_HXX
#include <sal/config.h>
#include <cassert>
#include <type_traits>
#include <utility>
#include <optional>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/uno/RuntimeException.hpp>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/XInterface.hpp>
#include <cppu/unotype.hxx>
#include <rtl/ustring.hxx>
#include <sal/types.h>
// Some functionality related to css::uno::Any that would ideally be part of
// <com/sun/star/uno/Any.hxx>, but (for now) cannot be for some reason.
namespace o3tl {
namespace detail {
struct Void {};
template <typename T> struct Optional { using type = T const *; };
template <> struct Optional<void > { using type = std::optional<Void const >; };
template <> struct Optional<bool > { using type = std::optional<bool const >; };
template <> struct Optional<sal_Int8> {
using type = std::optional<sal_Int8 const >;
};
template <> struct Optional<sal_Int16> {
using type = std::optional<sal_Int16 const >;
};
template <> struct Optional<sal_uInt16> {
using type = std::optional<sal_uInt16 const >;
};
template <> struct Optional<sal_Int32> {
using type = std::optional<sal_Int32 const >;
};
template <> struct Optional<sal_uInt32> {
using type = std::optional<sal_uInt32 const >;
};
template <> struct Optional<sal_Int64> {
using type = std::optional<sal_Int64 const >;
};
template <> struct Optional<sal_uInt64> {
using type = std::optional<sal_uInt64 const >;
};
template <> struct Optional<float > {
using type = std::optional<float const >;
};
template <> struct Optional<double > {
using type = std::optional<double const >;
};
template <typename T> struct Optional<css::uno::Reference<T>> {
using type = std::optional<css::uno::Reference<T> const >;
};
template <> struct Optional<css::uno::Reference<css::uno::XInterface>> {
using type = css::uno::Reference<css::uno::XInterface> const *;
};
template <typename > struct IsDerivedReference: std::false_type {};
template <typename T> struct IsDerivedReference<css::uno::Reference<T>>:
std::true_type
{};
template <> struct IsDerivedReference<css::uno::Reference<css::uno::XInterface>>:
std::false_type
{};
template <typename > struct IsUnoSequenceType: std::false_type {};
template <typename T> struct IsUnoSequenceType<cppu::UnoSequenceType<T>>:
std::true_type
{};
template <typename T> inline std::optional<T const > tryGetConverted(
css::uno::Any const & any)
{
T v;
return (any >>= v)
? std::optional<T const >(std::move(v)) : std::optional<T const >();
}
}
/** Try to access the value of a specific type stored in an Any.
In trying to obtain a value , the same set of conversions as supported by
" > > = " are considered .
The returned object is a proxy . Proxies can be either positive or negative .
Each proxy can be contextually converted to bool , yielding true iff the
proxy is positive . For a positive proxy P representing a value of requested
type T , for any T other than void , the expression * P yields that value of
type T . ( Technically , the proxy is either a plain pointer or a
std : : optional , depending on whether a plain pointer into the given Any can
be returned for the specified type . )
@ attention A proxy returned from this function must not outlive the
corresponding Any passed into this function ( as it may constitute a pointer
into the Any ' s internals ) . That is the reason why this function is
restricted to lvalue arguments ( i . e . , to non - temporary Any objects ) , to
avoid misuses like
@ code
css : : uno : : Any f ( ) ;
if ( auto p = o3tl : : tryAccess < css : : beans : : NamedValue > ( f ( ) ) ) {
return p - > Name ;
}
@ endcode
@ note Ideally this would be a public member function of css : : uno : : Any ( at
least conditional on LIBO_INTERNAL_ONLY , as it requires C + + 11 ) . However , as
std : : optional ( which would be needed to implement the proxies ) is only
available since C + + 14 , we need to use std : : optional for now . But To not
make every entity that includes < com / sun / star / uno / Any . hxx > depend on
boost_headers , keep this here for now .
@ tparam T the C + + representation of a UNO type that can be contained in a
UNO ANY ( i . e . , any UNO type other than ANY itself ) . The legacy C + +
representations sal_Bool , cppu : : UnoVoidType , cppu : : UnoUnsignedShortType ,
cppu : : UnoCharType , and cppu : : UnoSequenceType are not supported . Must be a
complete type or void .
@ param any an Any value .
@ return a positive proxy for the value of the specified type obtained from
the given Any , or a negative proxy if no such value can be obtained .
*/
template <typename T> inline
typename 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) {
// CHAR, STRING, TYPE, sequence types, enum types, struct types, exception
// types, and com.sun.star.uno.XInterface interface type:
return cppu::UnoType<T>::get().isAssignableFrom(any.getValueType())
? static_cast <T const *>(any.getValue()) : nullptr;
}
template <> inline detail::Optional<void >::type tryAccess<void >(
css::uno::Any const & any)
{
return any.hasValue()
? std::optional<detail::Void const >()
: std::optional<detail::Void const >(detail::Void ());
}
template <> inline detail::Optional<bool >::type tryAccess<bool >(
css::uno::Any const & any)
{
return detail::tryGetConverted<bool >(any);
}
template <> inline detail::Optional<sal_Int8>::type tryAccess<sal_Int8>(
css::uno::Any const & any)
{
return detail::tryGetConverted<sal_Int8>(any);
}
template <> inline detail::Optional<sal_Int16>::type tryAccess<sal_Int16>(
css::uno::Any const & any)
{
return detail::tryGetConverted<sal_Int16>(any);
}
template <> inline detail::Optional<sal_uInt16>::type tryAccess<sal_uInt16>(
css::uno::Any const & any)
{
return detail::tryGetConverted<sal_uInt16>(any);
}
template <> inline detail::Optional<sal_Int32>::type tryAccess<sal_Int32>(
css::uno::Any const & any)
{
return detail::tryGetConverted<sal_Int32>(any);
}
template <> inline detail::Optional<sal_uInt32>::type tryAccess<sal_uInt32>(
css::uno::Any const & any)
{
return detail::tryGetConverted<sal_uInt32>(any);
}
template <> inline detail::Optional<sal_Int64>::type tryAccess<sal_Int64>(
css::uno::Any const & any)
{
return detail::tryGetConverted<sal_Int64>(any);
}
template <> inline detail::Optional<sal_uInt64>::type tryAccess<sal_uInt64>(
css::uno::Any const & any)
{
return detail::tryGetConverted<sal_uInt64>(any);
}
template <> inline detail::Optional<float >::type tryAccess<float >(
css::uno::Any const & any)
{
return detail::tryGetConverted<float >(any);
}
template <> inline detail::Optional<double >::type tryAccess<double >(
css::uno::Any const & any)
{
return detail::tryGetConverted<double >(any);
}
template <> detail::Optional<css::uno::Any>::type tryAccess<css::uno::Any>(
css::uno::Any const &) = delete ;
template <> detail::Optional<sal_Bool>::type tryAccess<sal_Bool>(
css::uno::Any const &) = delete ;
/*
// Already prevented by std::is_base_of<css::uno::XInterface, T> requiring T to
// be complete:
template < > detail : : Optional < cppu : : UnoVoidType > : : type
tryAccess < cppu : : UnoVoidType > ( css : : uno : : Any const & ) = delete ;
template < > detail : : Optional < cppu : : UnoUnsignedShortType > : : type
tryAccess < cppu : : UnoUnsignedShortType > ( css : : uno : : Any const & ) = delete ;
template < > detail : : Optional < cppu : : UnoCharType > : : type
tryAccess < cppu : : UnoCharType > ( css : : uno : : Any const & ) = delete ;
*/
template <typename T> inline
typename std::enable_if<
detail::IsDerivedReference<T>::value,
typename detail::Optional<T>::type>::type
tryAccess(css::uno::Any const & any) {
return detail::tryGetConverted<T>(any);
}
template <typename T> typename detail::Optional<T>::type tryAccess(
css::uno::Any const volatile &&) = delete ;
/** Access the value of a specific type stored in an Any, throwing an exception
on failure .
@ attention A proxy returned from this function must not outlive the
corresponding Any passed into this function ( as it may constitute a pointer
into the Any ' s internals ) . However , unlike with tryAccess , the benefit of
allowing this function to operate on temporaries appears to outweigh its
dangers .
@ note Ideally this would be a public member function of css : : uno : : Any . See
tryAccess for details .
@ tparam T the C + + representation of a UNO type that can be contained in a
UNO ANY . See tryAccess for details .
@ param any an Any value .
@ return a positive proxy for the value of the specified type obtained from
the given Any . See tryAccess for details .
@ throws css : : uno : : RuntimeException when a value of the requested type
cannot be obtained .
*/
template <typename T> inline typename detail::Optional<T>::type doAccess(
css::uno::Any const & any)
{
auto opt = tryAccess<T>(any);
if (!opt) {
throw css::uno::RuntimeException(
OUString(
cppu_Any_extraction_failure_msg(
&any, cppu::UnoType<T>::get().getTypeLibType()),
SAL_NO_ACQUIRE));
}
return opt;
}
/** Access the value of a specific type stored in an Any, knowing the Any
contains a value of a matching type .
@ attention A proxy returned from this function must not outlive the
corresponding Any passed into this function ( as it may constitute a pointer
into the Any ' s internals ) . However , unlike with tryAccess , the benefit of
allowing this function to operate on temporaries appears to outweigh its
dangers .
@ note Ideally this would be a public member function of css : : uno : : Any . See
tryAccess for details .
@ tparam T the C + + representation of a UNO type that can be contained in a
UNO ANY . See tryAccess for details .
@ param any an Any value .
@ return a positive proxy for the value of the specified type obtained from
the given Any . See tryAccess for details .
*/
template <typename T> inline typename detail::Optional<T>::type forceAccess(
css::uno::Any const & any)
{
auto opt = tryAccess<T>(any);
assert(opt);
return opt;
}
}
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
Messung V0.5 in Prozent C=96 H=100 G=97
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland