Coverage Report

Created: 2026-01-09 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/upx/src/util/xspan_impl_span.h
Line
Count
Source
1
/* xspan -- a minimally invasive checked memory smart pointer
2
3
   This file is part of the UPX executable compressor.
4
5
   Copyright (C) Markus Franz Xaver Johannes Oberhumer
6
   All Rights Reserved.
7
8
   UPX and the UCL library are free software; you can redistribute them
9
   and/or modify them under the terms of the GNU General Public License as
10
   published by the Free Software Foundation; either version 2 of
11
   the License, or (at your option) any later version.
12
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
18
   You should have received a copy of the GNU General Public License
19
   along with this program; see the file COPYING.
20
   If not, write to the Free Software Foundation, Inc.,
21
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23
   Markus F.X.J. Oberhumer
24
   <markus@oberhumer.com>
25
 */
26
27
#pragma once
28
29
XSPAN_NAMESPACE_BEGIN
30
31
/*************************************************************************
32
// Span
33
//
34
// invariants:
35
//   ptr != null, base != null
36
//   ptr is valid in base
37
**************************************************************************/
38
39
template <class T>
40
struct Span {
41
private:
42
52.2k
#define CSelf Span
43
    typedef CSelf<T> Self;
44
    // core config
45
#if __cplusplus >= 201103L
46
    static constexpr bool configRequirePtr = true;
47
    static constexpr bool configRequireBase = true;
48
#else
49
    enum { configRequirePtr = true };
50
    enum { configRequireBase = true };
51
#endif
52
53
#include "xspan_impl_common.h"
54
public:
55
    // constructors from pointers
56
    CSelf(pointer first) XSPAN_DELETED_FUNCTION;
57
58
    // constructors
59
    CSelf(const Self &other)
60
408k
        : ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {
61
408k
        assertInvariants();
62
408k
    }
XSpan::Span<char>::Span(XSpan::Span<char> const&)
Line
Count
Source
60
20.9k
        : ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {
61
20.9k
        assertInvariants();
62
20.9k
    }
XSpan::Span<unsigned char>::Span(XSpan::Span<unsigned char> const&)
Line
Count
Source
60
524
        : ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {
61
524
        assertInvariants();
62
524
    }
XSpan::Span<unsigned char const>::Span(XSpan::Span<unsigned char const> const&)
Line
Count
Source
60
335k
        : ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {
61
335k
        assertInvariants();
62
335k
    }
XSpan::Span<LE32>::Span(XSpan::Span<LE32> const&)
Line
Count
Source
60
51.2k
        : ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {
61
51.2k
        assertInvariants();
62
51.2k
    }
Unexecuted instantiation: XSpan::Span<LE32 const>::Span(XSpan::Span<LE32 const> const&)
XSpan::Span<PeFile::import_desc>::Span(XSpan::Span<PeFile::import_desc> const&)
Line
Count
Source
60
171
        : ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {
61
171
        assertInvariants();
62
171
    }
63
    template <class U>
64
    CSelf(const CSelf<U> &other, XSPAN_REQUIRES_CONVERTIBLE_A)
65
0
        : ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {
66
0
        assertInvariants();
67
0
    }
68
69
    // constructors from Span friends
70
#if XSPAN_CONFIG_ENABLE_SPAN_CONVERSION
71
    template <class U>
72
    CSelf(const PtrOrSpanOrNull<U> &other, XSPAN_REQUIRES_CONVERTIBLE_A)
73
541
        : ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {
74
541
        assertInvariants();
75
541
    }
Unexecuted instantiation: XSpan::Span<unsigned char const>::Span<unsigned char>(XSpan::PtrOrSpanOrNull<unsigned char> const&, std::__1::enable_if<XSpan::XSpan_is_convertible<unsigned char, unsigned char const>::value, XSpan::XSpanInternalDummyArg>::type)
XSpan::Span<PeFile::Reloc::BaseReloc>::Span<PeFile::Reloc::BaseReloc>(XSpan::PtrOrSpanOrNull<PeFile::Reloc::BaseReloc> const&, std::__1::enable_if<XSpan::XSpan_is_convertible<PeFile::Reloc::BaseReloc, PeFile::Reloc::BaseReloc>::value, XSpan::XSpanInternalDummyArg>::type)
Line
Count
Source
73
541
        : ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {
74
541
        assertInvariants();
75
541
    }
Unexecuted instantiation: XSpan::Span<unsigned char>::Span<unsigned char>(XSpan::PtrOrSpanOrNull<unsigned char> const&, std::__1::enable_if<XSpan::XSpan_is_convertible<unsigned char, unsigned char>::value, XSpan::XSpanInternalDummyArg>::type)
76
    template <class U>
77
    CSelf(const PtrOrSpan<U> &other, XSPAN_REQUIRES_CONVERTIBLE_A)
78
        : ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {
79
        assertInvariants();
80
    }
81
#endif
82
83
    // assignment from Span friends
84
#if XSPAN_CONFIG_ENABLE_SPAN_CONVERSION
85
    // TODO: use Unchecked to avoid double checks in both constructor and assignment
86
    template <class U>
87
    XSPAN_REQUIRES_CONVERTIBLE_R(Self &)
88
    operator=(const PtrOrSpan<U> &other) {
89
        if (other.base == nullptr)
90
            return assign(Self(other.ptr, size_in_bytes, base));
91
        return assign(Self(other.ptr, other.size_in_bytes, other.base));
92
    }
93
    template <class U>
94
    XSPAN_REQUIRES_CONVERTIBLE_R(Self &)
95
0
    operator=(const PtrOrSpanOrNull<U> &other) {
96
0
        if (other.base == nullptr)
97
0
            return assign(Self(other.ptr, size_in_bytes, base));
98
0
        return assign(Self(other.ptr, other.size_in_bytes, other.base));
99
0
    }
100
#endif
101
102
    // nullptr
103
    CSelf(std::nullptr_t) XSPAN_DELETED_FUNCTION;
104
    CSelf(std::nullptr_t, XSpanCount, const void *) XSPAN_DELETED_FUNCTION;
105
    CSelf(std::nullptr_t, XSpanSizeInBytes, const void *) XSPAN_DELETED_FUNCTION;
106
    CSelf(std::nullptr_t, size_type, const void *) XSPAN_DELETED_FUNCTION;
107
    Self &operator=(std::nullptr_t) XSPAN_DELETED_FUNCTION;
108
#if 0
109
    // don't enable, this prevents generic usage
110
    bool operator==(std::nullptr_t) const XSPAN_DELETED_FUNCTION;
111
    bool operator!=(std::nullptr_t) const XSPAN_DELETED_FUNCTION;
112
#else
113
    bool operator==(std::nullptr_t) const {
114
        assertInvariants();
115
        return false;
116
    }
117
    bool operator!=(std::nullptr_t) const {
118
        assertInvariants();
119
        return true;
120
    }
121
#endif
122
#undef CSelf
123
};
124
125
// raw_bytes overload
126
template <class T>
127
144k
inline typename Span<T>::pointer raw_bytes(const Span<T> &a, size_t size_in_bytes) {
128
144k
    return a.raw_bytes(size_in_bytes);
129
144k
}
XSpan::Span<char>::pointer XSpan::raw_bytes<char>(XSpan::Span<char> const&, unsigned long)
Line
Count
Source
127
83.6k
inline typename Span<T>::pointer raw_bytes(const Span<T> &a, size_t size_in_bytes) {
128
83.6k
    return a.raw_bytes(size_in_bytes);
129
83.6k
}
XSpan::Span<unsigned char>::pointer XSpan::raw_bytes<unsigned char>(XSpan::Span<unsigned char> const&, unsigned long)
Line
Count
Source
127
7.35k
inline typename Span<T>::pointer raw_bytes(const Span<T> &a, size_t size_in_bytes) {
128
7.35k
    return a.raw_bytes(size_in_bytes);
129
7.35k
}
XSpan::Span<unsigned char const>::pointer XSpan::raw_bytes<unsigned char const>(XSpan::Span<unsigned char const> const&, unsigned long)
Line
Count
Source
127
53.2k
inline typename Span<T>::pointer raw_bytes(const Span<T> &a, size_t size_in_bytes) {
128
53.2k
    return a.raw_bytes(size_in_bytes);
129
53.2k
}
130
template <class T>
131
inline typename Span<T>::pointer raw_index_bytes(const Span<T> &a, size_t index,
132
83.6k
                                                 size_t size_in_bytes) {
133
83.6k
    typedef typename Span<T>::element_type element_type;
134
83.6k
    return a.raw_bytes(mem_size(sizeof(element_type), index, size_in_bytes)) + index;
135
83.6k
}
136
137
/*************************************************************************
138
//
139
**************************************************************************/
140
141
XSPAN_NAMESPACE_END
142
143
#if !XSPAN_CONFIG_ENABLE_IMPLICIT_CONVERSION || 1
144
145
#define C XSPAN_NS(Span)
146
#define D XSPAN_NS(PtrOrSpanOrNull)
147
#define E XSPAN_NS(PtrOrSpan)
148
#include "xspan_fwd.h"
149
#undef C
150
#undef D
151
#undef E
152
153
#endif
154
155
/* vim:set ts=4 sw=4 et: */