Skip to content

Commit 9a5a138

Browse files
authored
CTL: utility.h, use ctl::swap in string (#1227)
* Add ctl utility.h Implements forward, move, swap, and declval. This commit also adds a def for nullptr_t to cxx.inc. We need it now because the CTL headers stopped including anything from libc++, so we no longer get their basic types. * Use ctl::swap in string The STL spec says that swap is located in the string_view header anyawy. Performance-wise this is a noop, but it’s slightly cleaner.
1 parent a795017 commit 9a5a138

File tree

13 files changed

+117
-46
lines changed

13 files changed

+117
-46
lines changed

ctl/optional.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
#ifndef COSMOPOLITAN_CTL_OPTIONAL_H_
44
#define COSMOPOLITAN_CTL_OPTIONAL_H_
55
#include "new.h"
6-
#include <__utility/forward.h>
7-
#include <__utility/move.h>
8-
#include <__utility/swap.h>
6+
#include "utility.h"
97

108
namespace ctl {
119

@@ -32,7 +30,7 @@ class optional
3230

3331
optional(T&& value) : present_(true)
3432
{
35-
new (&value_) T(std::move(value));
33+
new (&value_) T(ctl::move(value));
3634
}
3735

3836
optional(const optional& other) : present_(other.present_)
@@ -44,7 +42,7 @@ class optional
4442
optional(optional&& other) noexcept : present_(other.present_)
4543
{
4644
if (other.present_)
47-
new (&value_) T(std::move(other.value_));
45+
new (&value_) T(ctl::move(other.value_));
4846
}
4947

5048
optional& operator=(const optional& other)
@@ -63,7 +61,7 @@ class optional
6361
if (this != &other) {
6462
reset();
6563
if (other.present_)
66-
new (&value_) T(std::move(other.value_));
64+
new (&value_) T(ctl::move(other.value_));
6765
present_ = other.present_;
6866
}
6967
return *this;
@@ -87,7 +85,7 @@ class optional
8785
{
8886
if (!present_)
8987
__builtin_trap();
90-
return std::move(value_);
88+
return ctl::move(value_);
9189
}
9290

9391
explicit operator bool() const noexcept
@@ -113,19 +111,19 @@ class optional
113111
{
114112
reset();
115113
present_ = true;
116-
new (&value_) T(std::forward<Args>(args)...);
114+
new (&value_) T(ctl::forward<Args>(args)...);
117115
}
118116

119117
void swap(optional& other) noexcept
120118
{
121-
using std::swap;
119+
using ctl::swap;
122120
if (present_ && other.present_) {
123121
swap(value_, other.value_);
124122
} else if (present_) {
125-
other.emplace(std::move(value_));
123+
other.emplace(ctl::move(value_));
126124
reset();
127125
} else if (other.present_) {
128-
emplace(std::move(other.value_));
126+
emplace(ctl::move(other.value_));
129127
other.reset();
130128
}
131129
}

ctl/string.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,7 @@ class string
8787

8888
void swap(string& s) noexcept
8989
{
90-
char tmp[__::string_size];
91-
__builtin_memcpy(tmp, blob, __::string_size);
92-
__builtin_memcpy(blob, s.blob, __::string_size);
93-
__builtin_memcpy(s.blob, tmp, __::string_size);
90+
ctl::swap(blob, s.blob);
9491
}
9592

9693
string(string&& s) noexcept

ctl/string_view.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
33
#ifndef COSMOPOLITAN_CTL_STRINGVIEW_H_
44
#define COSMOPOLITAN_CTL_STRINGVIEW_H_
5+
#include "utility.h"
56

67
namespace ctl {
78

ctl/unique_ptr.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
33
#ifndef COSMOPOLITAN_CTL_UNIQUE_PTR_H_
44
#define COSMOPOLITAN_CTL_UNIQUE_PTR_H_
5-
#include <__utility/forward.h>
6-
#include <__utility/move.h>
7-
#include <__utility/swap.h>
5+
#include "utility.h"
86

97
namespace ctl {
108

@@ -36,11 +34,11 @@ struct unique_ptr
3634
}
3735

3836
constexpr unique_ptr(pointer p, auto&& d) noexcept
39-
: p(p), d(std::forward<decltype(d)>(d))
37+
: p(p), d(ctl::forward<decltype(d)>(d))
4038
{
4139
}
4240

43-
constexpr unique_ptr(unique_ptr&& u) noexcept : p(u.p), d(std::move(u.d))
41+
constexpr unique_ptr(unique_ptr&& u) noexcept : p(u.p), d(ctl::move(u.d))
4442
{
4543
u.p = nullptr;
4644
}
@@ -89,7 +87,7 @@ struct unique_ptr
8987

9088
inline void swap(unique_ptr& r) noexcept
9189
{
92-
using std::swap;
90+
using ctl::swap;
9391
swap(p, r.p);
9492
swap(d, r.d);
9593
}
@@ -115,7 +113,7 @@ struct unique_ptr
115113
}
116114

117115
inline element_type& operator*() const
118-
noexcept(noexcept(*std::declval<pointer>()))
116+
noexcept(noexcept(*ctl::declval<pointer>()))
119117
{
120118
if (!p)
121119
__builtin_trap();
@@ -134,7 +132,7 @@ template<typename T, typename... Args>
134132
inline unique_ptr<T>
135133
make_unique(Args&&... args)
136134
{
137-
return unique_ptr<T>(new T(std::forward<Args>(args)...));
135+
return unique_ptr<T>(new T(ctl::forward<Args>(args)...));
138136
}
139137

140138
template<typename T>

ctl/utility.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*-
2+
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
3+
//
4+
// Copyright 2024 Justine Alexandra Roberts Tunney
5+
//
6+
// Permission to use, copy, modify, and/or distribute this software for
7+
// any purpose with or without fee is hereby granted, provided that the
8+
// above copyright notice and this permission notice appear in all copies.
9+
//
10+
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11+
// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12+
// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13+
// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14+
// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15+
// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16+
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17+
// PERFORMANCE OF THIS SOFTWARE.
18+
19+
#include "utility.h"

ctl/utility.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
2+
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
3+
#ifndef COSMOPOLITAN_CTL_UTILITY_H_
4+
#define COSMOPOLITAN_CTL_UTILITY_H_
5+
6+
namespace ctl {
7+
8+
namespace __ {
9+
10+
template<typename T>
11+
struct no_infer_
12+
{
13+
typedef T type;
14+
};
15+
16+
template<typename T>
17+
using no_infer = typename no_infer_<T>::type;
18+
19+
} // namespace __
20+
21+
template<typename T>
22+
constexpr T&&
23+
move(T& t) noexcept
24+
{
25+
return static_cast<T&&>(t);
26+
}
27+
28+
template<typename T>
29+
constexpr T&&
30+
forward(__::no_infer<T>& t) noexcept
31+
{
32+
return static_cast<T&&>(t);
33+
}
34+
35+
template<typename T>
36+
// TODO(mrdomino): requires move_constructible<T> && move_assignable<T>
37+
constexpr void
38+
swap(T& a, T& b) noexcept
39+
{
40+
T t(ctl::move(a));
41+
a = ctl::move(b);
42+
b = ctl::move(t);
43+
}
44+
45+
template<typename T, size_t N>
46+
// TODO(mrdomino): requires is_swappable
47+
constexpr void
48+
swap(T (&a)[N], T (&b)[N]) noexcept
49+
{
50+
for (size_t i = 0; i < N; ++i) {
51+
swap(a[i], b[i]);
52+
}
53+
}
54+
55+
template<typename T>
56+
T&&
57+
declval() noexcept;
58+
59+
} // namespace ctl
60+
61+
#endif // COSMOPOLITAN_CTL_UTILITY_H_

ctl/vector.h

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
#ifndef COSMOPOLITAN_CTL_OPTIONAL_H_
44
#define COSMOPOLITAN_CTL_OPTIONAL_H_
55
#include "new.h"
6-
#include <__utility/forward.h>
7-
#include <__utility/move.h>
8-
#include <__utility/swap.h>
6+
#include "utility.h"
97

108
namespace ctl {
119

@@ -173,7 +171,7 @@ struct vector
173171
return;
174172
T* newP = new T[c2];
175173
for (size_t i = 0; i < n; ++i)
176-
newP[i] = std::move(p[i]);
174+
newP[i] = ctl::move(p[i]);
177175
delete[] p;
178176
p = newP;
179177
c = c2;
@@ -197,7 +195,7 @@ struct vector
197195
c2 += c2 >> 1;
198196
reserve(c2);
199197
}
200-
new (&p[n]) T(std::forward<T>(e));
198+
new (&p[n]) T(ctl::forward<T>(e));
201199
++n;
202200
}
203201

@@ -209,7 +207,7 @@ struct vector
209207
c2 += c2 >> 1;
210208
reserve(c2);
211209
}
212-
new (&p[n]) T(std::forward<Args>(args)...);
210+
new (&p[n]) T(ctl::forward<Args>(args)...);
213211
++n;
214212
}
215213

@@ -236,9 +234,9 @@ struct vector
236234

237235
void swap(vector& other) noexcept
238236
{
239-
std::swap(n, other.n);
240-
std::swap(c, other.c);
241-
std::swap(p, other.p);
237+
ctl::swap(n, other.n);
238+
ctl::swap(c, other.c);
239+
ctl::swap(p, other.p);
242240
}
243241
};
244242

libc/integral/cxx.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,5 @@ struct __cxx_choose_expr<false, _T, _U> {
3939
/* todo jart whyyyy */
4040
#define _Float16 __fp16
4141
#endif
42+
43+
using nullptr_t = decltype(nullptr);

test/ctl/optional_test.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ main()
6363

6464
{
6565
ctl::optional<ctl::string> x("world");
66-
ctl::optional<ctl::string> y(std::move(x));
66+
ctl::optional<ctl::string> y(ctl::move(x));
6767
if (!y)
6868
return 9;
6969
if (!y.has_value())
@@ -87,7 +87,7 @@ main()
8787
{
8888
ctl::optional<ctl::string> x("hello");
8989
ctl::optional<ctl::string> y;
90-
y = std::move(x);
90+
y = ctl::move(x);
9191
if (!y)
9292
return 16;
9393
if (!y.has_value())

test/ctl/string_test.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "ctl/string.h"
2020

2121
#include <__type_traits/is_same.h>
22-
#include <__utility/move.h>
2322

2423
#include "libc/runtime/runtime.h"
2524
#include "libc/str/str.h"
@@ -211,7 +210,7 @@ main()
211210

212211
{
213212
String s = "hello";
214-
String s2 = std::move(s);
213+
String s2 = ctl::move(s);
215214
if (s2 != "hello")
216215
return 47;
217216
if (!s.empty())

0 commit comments

Comments
 (0)