LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / include / comphelper / interfacecontainer3.hxx
blob008f21db91ae39a69a03b74b120bff1bc4a429b7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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_COMPHELPER_INTERFACECONTAINER3_H
20 #define INCLUDED_COMPHELPER_INTERFACECONTAINER3_H
22 #include <sal/config.h>
24 #include <com/sun/star/lang/EventObject.hpp>
25 #include <com/sun/star/lang/DisposedException.hpp>
26 #include <o3tl/cow_wrapper.hxx>
27 #include <vector>
29 namespace com::sun::star::uno
31 class XInterface;
33 namespace osl
35 class Mutex;
38 /** */ //for docpp
39 namespace comphelper
41 template <class ListenerT> class OInterfaceContainerHelper3;
42 /**
43 This is the iterator of an OInterfaceContainerHelper3. Typically
44 one constructs an instance on the stack for one firing session.
45 It is not allowed to assign or copy an instance of this class.
47 @tparam ListenerT UNO event listener type
48 @see OInterfaceContainerHelper3
50 template <class ListenerT> class OInterfaceIteratorHelper3
52 public:
53 /**
54 Create an iterator over the elements of the container. The iterator
55 copies the elements of the container. A change to the container
56 during the lifetime of an iterator is allowed and does not
57 affect the iterator-instance. The iterator and the container take cares
58 themself for concurrent access, no additional guarding is necessary.
60 Remark: The copy is on demand. The iterator copy the elements only if the container
61 change the contents...
63 @param rCont the container of the elements.
65 OInterfaceIteratorHelper3(OInterfaceContainerHelper3<ListenerT>& rCont_)
66 : rCont(rCont_)
67 , maData(rCont.maData)
68 , nRemain(maData->size())
72 /** Return true, if there are more elements in the iterator. */
73 bool hasMoreElements() const { return nRemain != 0; }
74 /** Return the next element of the iterator. Calling this method if
75 hasMoreElements() has returned false, is an error.
77 css::uno::Reference<ListenerT> const& next();
79 /** Removes the current element (the last one returned by next())
80 from the underlying container. Calling this method before
81 next() has been called or calling it twice with no next()
82 in between is an error.
84 void remove();
86 private:
87 OInterfaceContainerHelper3<ListenerT>& rCont;
88 o3tl::cow_wrapper<std::vector<css::uno::Reference<ListenerT>>,
89 o3tl::ThreadSafeRefCountingPolicy>
90 maData;
91 sal_Int32 nRemain;
93 OInterfaceIteratorHelper3(const OInterfaceIteratorHelper3&) = delete;
94 OInterfaceIteratorHelper3& operator=(const OInterfaceIteratorHelper3&) = delete;
97 template <class ListenerT>
98 const css::uno::Reference<ListenerT>& OInterfaceIteratorHelper3<ListenerT>::next()
100 nRemain--;
101 return (*maData)[nRemain];
104 template <class ListenerT> void OInterfaceIteratorHelper3<ListenerT>::remove()
106 rCont.removeInterface((*maData)[nRemain]);
110 A container of interfaces. To access the elements use an iterator.
111 This implementation is thread-safe.
113 This is a copy of the code at include/comphelper/interfacecontainer2.hxx,
114 except that it is templatized on the type of the listener, which allows
115 some parts of the code to avoid doing an UNO_QUERY that can be expensive
116 in bulk.
118 @tparam ListenerT UNO event listener type
119 @see OInterfaceIteratorHelper
121 template <class ListenerT> class OInterfaceContainerHelper3
123 public:
125 Create an interface container.
127 @param rMutex the mutex to protect multi thread access.
128 The lifetime must be longer than the lifetime
129 of this object.
131 OInterfaceContainerHelper3(::osl::Mutex& rMutex_)
132 : rMutex(rMutex_)
136 Return the number of Elements in the container. Only useful if you have acquired
137 the mutex.
139 sal_Int32 getLength() const;
142 Return all interfaces added to this container.
144 std::vector<css::uno::Reference<ListenerT>> getElements() const;
146 /** Inserts an element into the container. The position is not specified, thus it is not
147 specified in which order events are fired.
149 @attention
150 If you add the same interface more than once, then it will be added to the elements list
151 more than once and thus if you want to remove that interface from the list, you have to call
152 removeInterface() the same number of times.
153 In the latter case, you will also get events fired more than once (if the interface is a
154 listener interface).
156 @param rxIFace
157 interface to be added; it is allowed to insert
158 the same interface more than once
159 @return
160 the new count of elements in the container
162 sal_Int32 addInterface(const css::uno::Reference<ListenerT>& rxIFace);
163 /** Removes an element from the container. It uses interface equality to remove the interface.
165 @param rxIFace
166 interface to be removed
167 @return
168 the new count of elements in the container
170 sal_Int32 removeInterface(const css::uno::Reference<ListenerT>& rxIFace);
172 Call disposing on all object in the container that
173 support XEventListener. Then clear the container.
175 void disposeAndClear(const css::lang::EventObject& rEvt);
177 Clears the container without calling disposing().
179 void clear();
181 /** Executes a functor for each contained listener of specified type, e.g.
182 <code>forEach<awt::XPaintListener>(...</code>.
184 If a css::lang::DisposedException occurs which relates to
185 the called listener, then that listener is removed from the container.
187 @tparam FuncT unary functor type, let your compiler deduce this for you
188 @param func unary functor object expecting an argument of type
189 css::uno::Reference<ListenerT>
191 template <typename FuncT> inline void forEach(FuncT const& func);
193 /** Calls a UNO listener method for each contained listener.
195 The listener method must take a single argument of type EventT,
196 and return <code>void</code>.
198 If a css::lang::DisposedException occurs which relates to
199 the called listener, then that listener is removed from the container.
201 @tparam EventT event type, let your compiler deduce this for you
202 @param NotificationMethod
203 Pointer to a method of a ListenerT interface.
204 @param Event
205 Event to notify to all contained listeners
207 Example:
208 @code
209 awt::PaintEvent aEvent( static_cast< cppu::OWeakObject* >( this ), ... );
210 listeners.notifyEach( &XPaintListener::windowPaint, aEvent );
211 @endcode
213 template <typename EventT>
214 inline void notifyEach(void (SAL_CALL ListenerT::*NotificationMethod)(const EventT&),
215 const EventT& Event);
217 private:
218 friend class OInterfaceIteratorHelper3<ListenerT>;
219 o3tl::cow_wrapper<std::vector<css::uno::Reference<ListenerT>>,
220 o3tl::ThreadSafeRefCountingPolicy>
221 maData;
222 ::osl::Mutex& rMutex;
223 OInterfaceContainerHelper3(const OInterfaceContainerHelper3&) = delete;
224 OInterfaceContainerHelper3& operator=(const OInterfaceContainerHelper3&) = delete;
226 private:
227 template <typename EventT> class NotifySingleListener
229 private:
230 typedef void (SAL_CALL ListenerT::*NotificationMethod)(const EventT&);
231 NotificationMethod const m_pMethod;
232 const EventT& m_rEvent;
234 public:
235 NotifySingleListener(NotificationMethod method, const EventT& event)
236 : m_pMethod(method)
237 , m_rEvent(event)
241 void operator()(const css::uno::Reference<ListenerT>& listener) const
243 (listener.get()->*m_pMethod)(m_rEvent);
248 template <class T>
249 template <typename FuncT>
250 inline void OInterfaceContainerHelper3<T>::forEach(FuncT const& func)
252 OInterfaceIteratorHelper3<T> iter(*this);
253 while (iter.hasMoreElements())
255 auto xListener = iter.next();
258 func(xListener);
260 catch (css::lang::DisposedException const& exc)
262 if (exc.Context == xListener)
263 iter.remove();
268 template <class ListenerT>
269 template <typename EventT>
270 inline void OInterfaceContainerHelper3<ListenerT>::notifyEach(
271 void (SAL_CALL ListenerT::*NotificationMethod)(const EventT&), const EventT& Event)
273 forEach<NotifySingleListener<EventT>>(NotifySingleListener<EventT>(NotificationMethod, Event));
276 template <class ListenerT> sal_Int32 OInterfaceContainerHelper3<ListenerT>::getLength() const
278 osl::MutexGuard aGuard(rMutex);
279 return maData->size();
282 template <class ListenerT>
283 std::vector<css::uno::Reference<ListenerT>>
284 OInterfaceContainerHelper3<ListenerT>::getElements() const
286 std::vector<css::uno::Reference<ListenerT>> rVec;
287 osl::MutexGuard aGuard(rMutex);
288 rVec = *maData;
289 return rVec;
292 template <class ListenerT>
293 sal_Int32
294 OInterfaceContainerHelper3<ListenerT>::addInterface(const css::uno::Reference<ListenerT>& rListener)
296 assert(rListener.is());
297 osl::MutexGuard aGuard(rMutex);
299 maData->push_back(rListener);
300 return maData->size();
303 template <class ListenerT>
304 sal_Int32 OInterfaceContainerHelper3<ListenerT>::removeInterface(
305 const css::uno::Reference<ListenerT>& rListener)
307 assert(rListener.is());
308 osl::MutexGuard aGuard(rMutex);
310 // It is not valid to compare the pointer directly, but it's faster.
311 auto it = std::find_if(maData->begin(), maData->end(),
312 [&rListener](const css::uno::Reference<css::uno::XInterface>& rItem) {
313 return rItem.get() == rListener.get();
316 // interface not found, use the correct compare method
317 if (it == maData->end())
318 it = std::find(maData->begin(), maData->end(), rListener);
320 if (it != maData->end())
321 maData->erase(it);
323 return maData->size();
326 template <class ListenerT>
327 void OInterfaceContainerHelper3<ListenerT>::disposeAndClear(const css::lang::EventObject& rEvt)
329 osl::ClearableMutexGuard aGuard(rMutex);
330 OInterfaceIteratorHelper3<ListenerT> aIt(*this);
331 maData->clear();
332 aGuard.clear();
333 while (aIt.hasMoreElements())
337 aIt.next()->disposing(rEvt);
339 catch (css::uno::RuntimeException&)
341 // be robust, if e.g. a remote bridge has disposed already.
342 // there is no way to delegate the error to the caller :o(.
347 template <class ListenerT> void OInterfaceContainerHelper3<ListenerT>::clear()
349 osl::MutexGuard aGuard(rMutex);
350 maData->clear();
353 #endif
355 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */