Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/canvas/inc/vclwrapper.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
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/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
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 .
18
 */
19
20
#pragma once
21
22
#include <vcl/svapp.hxx>
23
#include <memory>
24
25
namespace canvas
26
{
27
    namespace vcltools
28
    {
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.
32
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.
37
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.
42
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.".
52
         */
53
        template< class Wrappee_ > class VCLObject
54
        {
55
        public:
56
            typedef Wrappee_ Wrappee;
57
58
            VCLObject() :
59
0
                mpWrappee( new Wrappee() )
60
0
            {
61
0
            }
62
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 )
68
            {
69
            }
70
71
            // This object has value semantics, thus, forward copy
72
            // to wrappee
73
            VCLObject( const VCLObject& rOrig )
74
            {
75
                if( rOrig.mpWrappee )
76
                    mpWrappee = new Wrappee( *rOrig.mpWrappee );
77
                else
78
                    mpWrappee = nullptr;
79
            }
80
81
            VCLObject(VCLObject&& rOrig) noexcept
82
                : mpWrappee(std::move(rOrig.mpWrappee))
83
            {
84
            }
85
86
            // This object has value semantics, thus, forward copy
87
            // to wrappee
88
            VCLObject( const Wrappee& rOrig ) :
89
0
                mpWrappee( new Wrappee( rOrig ) )
90
0
            {
91
0
            }
Unexecuted instantiation: canvas::vcltools::VCLObject<vcl::Font>::VCLObject(vcl::Font const&)
Unexecuted instantiation: canvas::vcltools::VCLObject<Bitmap>::VCLObject(Bitmap const&)
92
93
            // This object has value semantics, thus, forward
94
            // assignment to wrappee
95
            VCLObject& operator=( const VCLObject& rhs )
96
            {
97
                if (this != &rhs)
98
                {
99
                    if( mpWrappee )
100
                    {
101
                        if( rhs.mpWrappee )
102
                            *mpWrappee = *rhs.mpWrappee;
103
                    }
104
                    else
105
                    {
106
                        if( rhs.mpWrappee )
107
                            mpWrappee = new Wrappee( *rhs.mpWrappee );
108
                    }
109
                }
110
                return *this;
111
            }
112
113
            VCLObject& operator=(VCLObject&& rhs) noexcept
114
0
            {
115
0
                std::swap(mpWrappee, rhs.mpWrappee);
116
117
0
                return *this;
118
0
            }
119
120
            ~VCLObject()
121
0
            {
122
                // This here is the whole purpose of the template:
123
                // protecting object deletion with the solar mutex
124
0
                SolarMutexGuard aGuard;
125
126
0
                mpWrappee.reset();
127
0
            }
Unexecuted instantiation: canvas::vcltools::VCLObject<Bitmap>::~VCLObject()
Unexecuted instantiation: canvas::vcltools::VCLObject<vcl::Font>::~VCLObject()
128
129
0
            Wrappee*        operator->() { return mpWrappee.get(); }
Unexecuted instantiation: canvas::vcltools::VCLObject<vcl::Font>::operator->()
Unexecuted instantiation: canvas::vcltools::VCLObject<Bitmap>::operator->()
130
0
            const Wrappee*  operator->() const { return mpWrappee.get(); }
131
132
0
            Wrappee&        operator*() { return *mpWrappee; }
133
0
            const Wrappee&  operator*() const { return *mpWrappee; }
Unexecuted instantiation: canvas::vcltools::VCLObject<vcl::Font>::operator*() const
Unexecuted instantiation: canvas::vcltools::VCLObject<Bitmap>::operator*() const
134
135
0
            Wrappee&        get() { return *mpWrappee; }
136
            const Wrappee&  get() const { return *mpWrappee; }
137
138
            void swap( VCLObject& rOther )
139
            {
140
                ::std::swap( mpWrappee, rOther.mpWrappee );
141
            }
142
143
        private:
144
145
            std::unique_ptr<Wrappee> mpWrappee;
146
        };
147
148
    }
149
}
150
151
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */