File: valueptr.h

package info (click to toggle)
cppcheck 2.17.1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 25,384 kB
  • sloc: cpp: 263,341; python: 19,737; ansic: 7,953; sh: 1,018; makefile: 996; xml: 994; cs: 291
file content (99 lines) | stat: -rw-r--r-- 2,612 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/* -*- C++ -*-
 * Cppcheck - A tool for static C/C++ code analysis
 * Copyright (C) 2007-2024 Cppcheck team.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

//---------------------------------------------------------------------------
#ifndef valueptrH
#define valueptrH
//---------------------------------------------------------------------------

#include "config.h"

#include <memory>

template<class T>
class CPPCHECKLIB ValuePtr {
    template<class U>
    struct cloner {
        static T* apply(const T* x) {
            return new U(*static_cast<const U*>(x));
        }
    };

public:
    using pointer = T*;
    using element_type = T;
    using cloner_type = decltype(&cloner<T>::apply);

    ValuePtr() : mPtr(nullptr), mClone() {}

    template<class U>
    // cppcheck-suppress noExplicitConstructor
    // NOLINTNEXTLINE(google-explicit-constructor)
    ValuePtr(const U& value) : mPtr(cloner<U>::apply(&value)), mClone(&cloner<U>::apply)
    {}

    ValuePtr(const ValuePtr& rhs) : mPtr(nullptr), mClone(rhs.mClone) {
        if (rhs) {
            mPtr.reset(mClone(rhs.get()));
        }
    }
    ValuePtr(ValuePtr&& rhs) NOEXCEPT : mPtr(std::move(rhs.mPtr)), mClone(std::move(rhs.mClone)) {}

    T* get() NOEXCEPT {
        return mPtr.get();
    }
    const T* get() const NOEXCEPT {
        return mPtr.get();
    }

    T& operator*() {
        return *get();
    }
    const T& operator*() const {
        return *get();
    }

    T* operator->() NOEXCEPT {
        return get();
    }
    const T* operator->() const NOEXCEPT {
        return get();
    }

    void swap(ValuePtr& rhs) NOEXCEPT {
        using std::swap;
        swap(mPtr, rhs.mPtr);
        swap(mClone, rhs.mClone);
    }

    ValuePtr<T>& operator=(ValuePtr rhs) & {
        swap(rhs);
        return *this;
    }

    // NOLINTNEXTLINE(google-explicit-constructor)
    operator bool() const NOEXCEPT {
        return !!mPtr;
    }

private:
    std::shared_ptr<T> mPtr;
    cloner_type mClone;
};

#endif