Skip to content

Commit 755e3a8

Browse files
committed
Move StringData to its own header
Now that it isn't just used for `Value`, it doesn't really belong in there.
1 parent a1e4824 commit 755e3a8

File tree

3 files changed

+98
-89
lines changed

3 files changed

+98
-89
lines changed

src/libexpr/include/nix/expr/static-string-data.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22
///@file
33

4-
#include "nix/expr/value.hh"
4+
#include "nix/expr/string-data.hh"
55

66
namespace nix {
77

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#pragma once
2+
///@file
3+
4+
#include <cstddef>
5+
#include <cstring>
6+
#include <memory_resource>
7+
#include <string_view>
8+
9+
namespace nix {
10+
11+
class StringData
12+
{
13+
public:
14+
using size_type = std::size_t;
15+
16+
size_type size_;
17+
char data_[];
18+
19+
/*
20+
* This in particular ensures that we cannot have a `StringData`
21+
* that we use by value, which is just what we want!
22+
*
23+
* Dynamically sized types aren't a thing in C++ and even flexible array
24+
* members are a language extension and beyond the realm of standard C++.
25+
* Technically, sizeof data_ member is 0 and the intended way to use flexible
26+
* array members is to allocate sizeof(StrindData) + count * sizeof(char) bytes
27+
* and the compiler will consider alignment restrictions for the FAM.
28+
*
29+
*/
30+
31+
StringData(StringData &&) = delete;
32+
StringData & operator=(StringData &&) = delete;
33+
StringData(const StringData &) = delete;
34+
StringData & operator=(const StringData &) = delete;
35+
~StringData() = default;
36+
37+
private:
38+
StringData() = delete;
39+
40+
explicit StringData(size_type size)
41+
: size_(size)
42+
{
43+
}
44+
45+
public:
46+
/**
47+
* Allocate StringData on the (possibly) GC-managed heap and copy
48+
* the contents of s to it.
49+
*/
50+
static const StringData & make(std::string_view s);
51+
52+
/**
53+
* Allocate StringData on the (possibly) GC-managed heap.
54+
* @param size Length of the string (without the NUL terminator).
55+
*/
56+
static StringData & alloc(size_t size);
57+
58+
size_t size() const
59+
{
60+
return size_;
61+
}
62+
63+
char * data() noexcept
64+
{
65+
return data_;
66+
}
67+
68+
const char * data() const noexcept
69+
{
70+
return data_;
71+
}
72+
73+
const char * c_str() const noexcept
74+
{
75+
return data_;
76+
}
77+
78+
constexpr std::string_view view() const noexcept
79+
{
80+
return std::string_view(data_, size_);
81+
}
82+
83+
template<size_t N>
84+
struct Static;
85+
86+
static StringData & make(std::pmr::memory_resource & resource, std::string_view s)
87+
{
88+
auto & res =
89+
*new (resource.allocate(sizeof(StringData) + s.size() + 1, alignof(StringData))) StringData(s.size());
90+
std::memcpy(res.data_, s.data(), s.size());
91+
res.data_[s.size()] = '\0';
92+
return res;
93+
}
94+
};
95+
96+
} // namespace nix

src/libexpr/include/nix/expr/value.hh

Lines changed: 1 addition & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,14 @@
33

44
#include <bit>
55
#include <cassert>
6-
#include <cstddef>
7-
#include <cstring>
86
#include <memory>
9-
#include <memory_resource>
107
#include <span>
118
#include <string_view>
129
#include <type_traits>
1310
#include <concepts>
1411

1512
#include "nix/expr/eval-gc.hh"
13+
#include "nix/expr/string-data.hh"
1614
#include "nix/expr/value/context.hh"
1715
#include "nix/util/source-path.hh"
1816
#include "nix/expr/print-options.hh"
@@ -192,91 +190,6 @@ public:
192190
friend struct Value;
193191
};
194192

195-
class StringData
196-
{
197-
public:
198-
using size_type = std::size_t;
199-
200-
size_type size_;
201-
char data_[];
202-
203-
/*
204-
* This in particular ensures that we cannot have a `StringData`
205-
* that we use by value, which is just what we want!
206-
*
207-
* Dynamically sized types aren't a thing in C++ and even flexible array
208-
* members are a language extension and beyond the realm of standard C++.
209-
* Technically, sizeof data_ member is 0 and the intended way to use flexible
210-
* array members is to allocate sizeof(StrindData) + count * sizeof(char) bytes
211-
* and the compiler will consider alignment restrictions for the FAM.
212-
*
213-
*/
214-
215-
StringData(StringData &&) = delete;
216-
StringData & operator=(StringData &&) = delete;
217-
StringData(const StringData &) = delete;
218-
StringData & operator=(const StringData &) = delete;
219-
~StringData() = default;
220-
221-
private:
222-
StringData() = delete;
223-
224-
explicit StringData(size_type size)
225-
: size_(size)
226-
{
227-
}
228-
229-
public:
230-
/**
231-
* Allocate StringData on the (possibly) GC-managed heap and copy
232-
* the contents of s to it.
233-
*/
234-
static const StringData & make(std::string_view s);
235-
236-
/**
237-
* Allocate StringData on the (possibly) GC-managed heap.
238-
* @param size Length of the string (without the NUL terminator).
239-
*/
240-
static StringData & alloc(size_t size);
241-
242-
size_t size() const
243-
{
244-
return size_;
245-
}
246-
247-
char * data() noexcept
248-
{
249-
return data_;
250-
}
251-
252-
const char * data() const noexcept
253-
{
254-
return data_;
255-
}
256-
257-
const char * c_str() const noexcept
258-
{
259-
return data_;
260-
}
261-
262-
constexpr std::string_view view() const noexcept
263-
{
264-
return std::string_view(data_, size_);
265-
}
266-
267-
template<size_t N>
268-
struct Static;
269-
270-
static StringData & make(std::pmr::memory_resource & resource, std::string_view s)
271-
{
272-
auto & res =
273-
*new (resource.allocate(sizeof(StringData) + s.size() + 1, alignof(StringData))) StringData(s.size());
274-
std::memcpy(res.data_, s.data(), s.size());
275-
res.data_[s.size()] = '\0';
276-
return res;
277-
}
278-
};
279-
280193
namespace detail {
281194

282195
/**

0 commit comments

Comments
 (0)