From 940b4d1848e8c70ab7642901a68594e8016caffc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 18:51:28 +0200 Subject: Adding upstream version 1:7.0.4. Signed-off-by: Daniel Baumann --- include/o3tl/any.hxx | 325 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100644 include/o3tl/any.hxx (limited to 'include/o3tl/any.hxx') diff --git a/include/o3tl/any.hxx b/include/o3tl/any.hxx new file mode 100644 index 000000000..0acccff64 --- /dev/null +++ b/include/o3tl/any.hxx @@ -0,0 +1,325 @@ +/* -*- 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 + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +// Some functionality related to css::uno::Any that would ideally be part of +// , but (for now) cannot be for some reason. + +namespace o3tl { + +namespace detail { + +struct Void {}; + +template struct Optional { using type = T const *; }; +template<> struct Optional { using type = std::optional; }; +template<> struct Optional { using type = std::optional; }; +template<> struct Optional { + using type = std::optional; +}; +template<> struct Optional { + using type = std::optional; +}; +template<> struct Optional { + using type = std::optional; +}; +template<> struct Optional { + using type = std::optional; +}; +template<> struct Optional { + using type = std::optional; +}; +template<> struct Optional { + using type = std::optional; +}; +template<> struct Optional { + using type = std::optional; +}; +template<> struct Optional { + using type = std::optional; +}; +template<> struct Optional { + using type = std::optional; +}; +template struct Optional> { + using type = std::optional const>; +}; +template<> struct Optional> { + using type = css::uno::Reference const *; +}; + +template struct IsDerivedReference: std::false_type {}; +template struct IsDerivedReference>: + std::true_type +{}; +template<> struct IsDerivedReference>: + std::false_type +{}; + +template struct IsUnoSequenceType: std::false_type {}; +template struct IsUnoSequenceType>: + std::true_type +{}; + +template inline std::optional tryGetConverted( + css::uno::Any const & any) +{ + T v; + return (any >>= v) + ? std::optional(std::move(v)) : std::optional(); +} + +} + +/** 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(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 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 inline +typename std::enable_if< + !(detail::IsDerivedReference::value + || detail::IsUnoSequenceType::value + || std::is_base_of::value), + typename detail::Optional::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::get().isAssignableFrom(any.getValueType()) + ? static_cast(any.getValue()) : nullptr; +} + +template<> inline detail::Optional::type tryAccess( + css::uno::Any const & any) +{ + return any.hasValue() + ? std::optional() + : std::optional(detail::Void()); +} + +template<> inline detail::Optional::type tryAccess( + css::uno::Any const & any) +{ + return detail::tryGetConverted(any); +} + +template<> inline detail::Optional::type tryAccess( + css::uno::Any const & any) +{ + return detail::tryGetConverted(any); +} + +template<> inline detail::Optional::type tryAccess( + css::uno::Any const & any) +{ + return detail::tryGetConverted(any); +} + +template<> inline detail::Optional::type tryAccess( + css::uno::Any const & any) +{ + return detail::tryGetConverted(any); +} + +template<> inline detail::Optional::type tryAccess( + css::uno::Any const & any) +{ + return detail::tryGetConverted(any); +} + +template<> inline detail::Optional::type tryAccess( + css::uno::Any const & any) +{ + return detail::tryGetConverted(any); +} + +template<> inline detail::Optional::type tryAccess( + css::uno::Any const & any) +{ + return detail::tryGetConverted(any); +} + +template<> inline detail::Optional::type tryAccess( + css::uno::Any const & any) +{ + return detail::tryGetConverted(any); +} + +template<> inline detail::Optional::type tryAccess( + css::uno::Any const & any) +{ + return detail::tryGetConverted(any); +} + +template<> inline detail::Optional::type tryAccess( + css::uno::Any const & any) +{ + return detail::tryGetConverted(any); +} + +template<> detail::Optional::type tryAccess( + css::uno::Any const &) = delete; + +template<> detail::Optional::type tryAccess( + css::uno::Any const &) = delete; + +/* + +// Already prevented by std::is_base_of requiring T to +// be complete: + +template<> detail::Optional::type +tryAccess(css::uno::Any const &) = delete; + +template<> detail::Optional::type +tryAccess(css::uno::Any const &) = delete; + +template<> detail::Optional::type +tryAccess(css::uno::Any const &) = delete; + +*/ + +template inline +typename std::enable_if< + detail::IsDerivedReference::value, + typename detail::Optional::type>::type +tryAccess(css::uno::Any const & any) { + return detail::tryGetConverted(any); +} + +template typename detail::Optional::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 inline typename detail::Optional::type doAccess( + css::uno::Any const & any) +{ + auto opt = tryAccess(any); + if (!opt) { + throw css::uno::RuntimeException( + OUString( + cppu_Any_extraction_failure_msg( + &any, cppu::UnoType::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 inline typename detail::Optional::type forceAccess( + css::uno::Any const & any) +{ + auto opt = tryAccess(any); + assert(opt); + return opt; +} + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ -- cgit v1.2.3