1+ // Copyright Contributors to the OpenImageIO project.
2+ // SPDX-License-Identifier: Apache-2.0
3+ // https://github.com/AcademySoftwareFoundation/OpenImageIO
4+
5+
6+ // ///////////////////////////////////////////////////////////////////////
7+ // / @file memory.h
8+ // /
9+ // / @brief Utilities for memory tracking.
10+ // ///////////////////////////////////////////////////////////////////////
11+
12+
13+ #pragma once
14+
15+ #define OPENIMAGEIO_MEMORY_H
16+
17+ #include < cstring>
18+ #include < memory>
19+ #include < vector>
20+
21+ OIIO_NAMESPACE_BEGIN
22+
23+ namespace pvt {
24+
25+ // / Return the total heap memory allocated by `object`.
26+ // / The template specialization can be used to give improved results for non trivial types
27+ // / that perform heap allocation, and to include members allocations recursively.
28+ template <typename T>
29+ inline size_t
30+ heapsize (const T& t)
31+ {
32+ return 0 ;
33+ }
34+
35+ // / Return the total memory footprint of `object`. If possible, including any heap
36+ // / allocations done by any constituent parts. The default implementation just reduces
37+ // / to sizeof(object), given that heapsize(object) would return 0.
38+ // / The template specialization can be used to give improved results for non trivial types
39+ // / that perform heap allocation.
40+ template <typename T>
41+ inline size_t
42+ footprint (const T& t)
43+ {
44+ if constexpr (std::is_pointer<T>::value)
45+ return sizeof (T) + (t ? footprint (*t) : 0 );
46+ else
47+ return sizeof (T) + heapsize (t);
48+ }
49+
50+
51+ // / Specializations for common STL types
52+
53+
54+ // heapsize specialization for std::string
55+ template <>
56+ inline size_t
57+ heapsize<std::string>(const std::string& s)
58+ {
59+ // accounts for small string optimization that does not
60+ // use any heap allocations
61+ const char * const sbegin = (const char *)&s;
62+ const char * const send = sbegin + sizeof (std::string);
63+ const char * const sdata = s.data ();
64+ const bool is_small = sdata >= sbegin && sdata < send;
65+ return is_small ? 0 : s.capacity ();
66+ }
67+
68+ // heapsize specialization for std::vector
69+ template <typename T>
70+ inline size_t
71+ heapsize (const std::vector<T>& vec)
72+ {
73+ size_t size = 0 ;
74+ for (const T& elem : vec)
75+ size += footprint (elem);
76+ return size;
77+ }
78+
79+ // heapsize specialization for std::shared_ptr
80+ template <typename T>
81+ inline size_t
82+ heapsize (const std::shared_ptr<T>& ref)
83+ {
84+ return ref ? footprint (*ref.get ()) : 0 ;
85+ }
86+
87+ // footprint specialization for std::shared_ptr
88+ template <typename T>
89+ inline size_t
90+ footprint (const std::shared_ptr<T>& ref)
91+ {
92+ return sizeof (std::shared_ptr<T>) + heapsize (ref);
93+ }
94+
95+ // heapsize specialization for std::unique_ptr
96+ template <typename T>
97+ inline size_t
98+ heapsize (const std::unique_ptr<T>& ref)
99+ {
100+ return ref ? footprint (*ref.get ()) : 0 ;
101+ }
102+
103+ // footprint specialization for std::unique_ptr
104+ template <typename T>
105+ inline size_t
106+ footprint (const std::unique_ptr<T>& ref)
107+ {
108+ return sizeof (std::unique_ptr<T>) + heapsize (ref);
109+ }
110+
111+ } // namespace pvt
112+
113+
114+ OIIO_NAMESPACE_END
0 commit comments