use --binary flag when applying patches with patch from git-bash
[LibreOffice.git] / canvas / inc / vclwrapper.hxx
blob3c1dfbf2d6862c2d77db6b2a84c76c58391475a5
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 .
20 #pragma once
22 #include <vcl/svapp.hxx>
23 #include <memory>
25 namespace canvas
27 namespace vcltools
29 /** This helper template wraps VCL objects, and protects
30 object deletion with the Solar mutex. All other operations
31 are unprotected, this must be handled by client code.
33 The reason for this template is the fact that VCL objects
34 hold by value in uno::Reference-handled classes are
35 deleted without having the chance to get inbetween and
36 lock the solar mutex.
38 This template handles that problem transparently, the only
39 inconvenience is the fact that object member access now
40 has to be performed via operator->, since . is not
41 overloadable.
43 Otherwise, the template preserves the value semantics of
44 the wrapped object, that is, copy operations are performed
45 not by copying pointers, but by copying the underlying
46 object. This includes constness, i.e. on a const
47 VCLObject, only const methods of the wrapped object can be
48 called. Simply imagine this to be a value object of type
49 "template argument", with the only peculiarity that
50 member/method access is performed by operator-> instead of
51 the non-existing "operator.".
53 template< class Wrappee_ > class VCLObject
55 public:
56 typedef Wrappee_ Wrappee;
58 VCLObject() :
59 mpWrappee( new Wrappee() )
63 // no explicit here. VCLObjects should be freely
64 // constructible with Wrappees, and AFAIK there is no other
65 // implicit conversion path that could cause harm here
66 VCLObject( std::unique_ptr<Wrappee> pWrappee ) :
67 mpWrappee( pWrappee )
71 // This object has value semantics, thus, forward copy
72 // to wrappee
73 VCLObject( const VCLObject& rOrig )
75 if( rOrig.mpWrappee )
76 mpWrappee = new Wrappee( *rOrig.mpWrappee );
77 else
78 mpWrappee = nullptr;
81 VCLObject(VCLObject&& rOrig) noexcept
82 : mpWrappee(std::move(rOrig.mpWrappee))
86 // This object has value semantics, thus, forward copy
87 // to wrappee
88 VCLObject( const Wrappee& rOrig ) :
89 mpWrappee( new Wrappee( rOrig ) )
93 // This object has value semantics, thus, forward
94 // assignment to wrappee
95 VCLObject& operator=( const VCLObject& rhs )
97 if (this != &rhs)
99 if( mpWrappee )
101 if( rhs.mpWrappee )
102 *mpWrappee = *rhs.mpWrappee;
104 else
106 if( rhs.mpWrappee )
107 mpWrappee = new Wrappee( *rhs.mpWrappee );
110 return *this;
113 VCLObject& operator=(VCLObject&& rhs) noexcept
115 std::swap(mpWrappee, rhs.mpWrappee);
117 return *this;
120 ~VCLObject()
122 // This here is the whole purpose of the template:
123 // protecting object deletion with the solar mutex
124 SolarMutexGuard aGuard;
126 mpWrappee.reset();
129 Wrappee* operator->() { return mpWrappee.get(); }
130 const Wrappee* operator->() const { return mpWrappee.get(); }
132 Wrappee& operator*() { return *mpWrappee; }
133 const Wrappee& operator*() const { return *mpWrappee; }
135 Wrappee& get() { return *mpWrappee; }
136 const Wrappee& get() const { return *mpWrappee; }
138 void swap( VCLObject& rOther )
140 ::std::swap( mpWrappee, rOther.mpWrappee );
143 private:
145 std::unique_ptr<Wrappee> mpWrappee;
151 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */