File: generic_object.hpp

package info (click to toggle)
sight 25.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 43,252 kB
  • sloc: cpp: 310,629; xml: 17,622; ansic: 9,960; python: 1,379; sh: 144; makefile: 33
file content (157 lines) | stat: -rw-r--r-- 5,216 bytes parent folder | download | duplicates (2)
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/************************************************************************
 *
 * Copyright (C) 2009-2024 IRCAD France
 * Copyright (C) 2012-2016 IHU Strasbourg
 *
 * This file is part of Sight.
 *
 * Sight is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Sight 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with Sight. If not, see <https://www.gnu.org/licenses/>.
 *
 ***********************************************************************/

#pragma once

#include <sight/data/config.hpp>

#include "data/timeline/buffer.hpp"

namespace sight::data::timeline
{

/**
 * @brief   This class is the non-template part of the class generic_object. It is used to store groups of objects
 *          inside a timeline. The maximum number of elements inside an object is fixed, however some elements
 *          can be missing. A mask is provided to test the presence of a given element.
 *          Note that the size of an element is not determined by dividing the size of the buffer by the maximum
 *          number of elements. Thus it is possible to have objects bigger
 */
class SIGHT_DATA_CLASS_API generic_object_base : public data::timeline::buffer
{
public:

    /// Destructor
    SIGHT_DATA_API ~generic_object_base() override;

    /// Return the number of elements present in the object
    [[nodiscard]] SIGHT_DATA_API unsigned int get_present_element_num() const;

    /// Tell if an element is present at the given index
    [[nodiscard]] SIGHT_DATA_API bool is_present(unsigned int _index) const;

    /// Return the raw presence mask
    [[nodiscard]] SIGHT_DATA_API uint64_t get_mask() const;

    /// Return the maximum number of elements in the buffer
    [[nodiscard]] SIGHT_DATA_API unsigned int get_max_element_num() const;

    /// Return the size of element in the buffer
    [[nodiscard]] SIGHT_DATA_API std::size_t get_element_size() const;

    /// Make a copy of this buffer
    SIGHT_DATA_API void deep_copy(const data::timeline::object& _other) override;

protected:

    /// Constructor
    SIGHT_DATA_API generic_object_base(
        unsigned int _max_element_num,
        core::clock::type _timestamp = 0,
        buffer_data_t _buffer        = nullptr,
        std::size_t _size            = 0,
        deleter_t _d                 = nullptr
    );

    /// Number of elements that are actually set
    unsigned int m_num_present {0};
    /// Binary mask that indicates which element are set
    uint64_t m_presence_mask {0};
    /// Maximum number of elements in an object
    unsigned int m_max_element_num;
};

/**
 * @brief   This timeline is used to store a group of objects of a given type. The maximum number of elements inside an
 *          object is fixed, however some elements can be missing. A mask is provided to test the presence of a given
 *          element.
 */
template<typename TYPE>
class generic_object : public generic_object_base
{
public:

    /// Type of the elements inside the buffer
    using element_t = TYPE;

    class iterator
    {
    public:

        /// Go to the next element
        void operator++();

        /// True if the current element is valid.
        [[nodiscard]] bool is_valid() const
        {
            return m_current_index < m_max_element;
        }

        /// Get the current element
        const element_t& operator*() const;

    private:

        /// Constructor
        iterator(const generic_object_base& _object);

        /// Pointer on the buffer object
        const generic_object_base* m_object;

        /// Current element
        unsigned int m_current_index {0};

        /// Maximum number of elements in the buffer
        unsigned int m_max_element;

        friend class generic_object<element_t>;
    };

    friend class iterator;

    /// Constructor
    generic_object(
        unsigned int _m_max_element_num,
        core::clock::type _timestamp = 0,
        buffer_data_t _buffer        = nullptr,
        std::size_t _size            = 0,
        deleter_t _d                 = nullptr
    );

    /// Destructor
    ~generic_object() override;

    /// Return the nth element in the buffer
    [[nodiscard]] const TYPE& get_element(unsigned int _index) const;

    /// Set the nth element in the buffer. Element in parameter will be copied at the given index. The method is
    /// disabled if TYPE isn't TriviallyCopyable because setElement internally uses memcpy.
    void set_element(const element_t& _element, unsigned int _index);

    /// Add an element and return a pointer on the newly added element
    TYPE* add_element(unsigned int _index);

    /// Return an iterator on the elements present in the object
    [[nodiscard]] iterator get_presence_iterator() const;
};

} // namespace sight::data::timeline