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.
This commit is contained in:
Steven Dee (Jōshin) 2024-06-18 22:00:59 -07:00 committed by GitHub
parent a795017416
commit 9a5a13854d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 117 additions and 46 deletions

View file

@ -3,9 +3,7 @@
#ifndef COSMOPOLITAN_CTL_OPTIONAL_H_
#define COSMOPOLITAN_CTL_OPTIONAL_H_
#include "new.h"
#include <__utility/forward.h>
#include <__utility/move.h>
#include <__utility/swap.h>
#include "utility.h"
namespace ctl {
@ -32,7 +30,7 @@ class optional
optional(T&& value) : present_(true)
{
new (&value_) T(std::move(value));
new (&value_) T(ctl::move(value));
}
optional(const optional& other) : present_(other.present_)
@ -44,7 +42,7 @@ class optional
optional(optional&& other) noexcept : present_(other.present_)
{
if (other.present_)
new (&value_) T(std::move(other.value_));
new (&value_) T(ctl::move(other.value_));
}
optional& operator=(const optional& other)
@ -63,7 +61,7 @@ class optional
if (this != &other) {
reset();
if (other.present_)
new (&value_) T(std::move(other.value_));
new (&value_) T(ctl::move(other.value_));
present_ = other.present_;
}
return *this;
@ -87,7 +85,7 @@ class optional
{
if (!present_)
__builtin_trap();
return std::move(value_);
return ctl::move(value_);
}
explicit operator bool() const noexcept
@ -113,19 +111,19 @@ class optional
{
reset();
present_ = true;
new (&value_) T(std::forward<Args>(args)...);
new (&value_) T(ctl::forward<Args>(args)...);
}
void swap(optional& other) noexcept
{
using std::swap;
using ctl::swap;
if (present_ && other.present_) {
swap(value_, other.value_);
} else if (present_) {
other.emplace(std::move(value_));
other.emplace(ctl::move(value_));
reset();
} else if (other.present_) {
emplace(std::move(other.value_));
emplace(ctl::move(other.value_));
other.reset();
}
}

View file

@ -87,10 +87,7 @@ class string
void swap(string& s) noexcept
{
char tmp[__::string_size];
__builtin_memcpy(tmp, blob, __::string_size);
__builtin_memcpy(blob, s.blob, __::string_size);
__builtin_memcpy(s.blob, tmp, __::string_size);
ctl::swap(blob, s.blob);
}
string(string&& s) noexcept

View file

@ -2,6 +2,7 @@
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
#ifndef COSMOPOLITAN_CTL_STRINGVIEW_H_
#define COSMOPOLITAN_CTL_STRINGVIEW_H_
#include "utility.h"
namespace ctl {

View file

@ -2,9 +2,7 @@
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
#ifndef COSMOPOLITAN_CTL_UNIQUE_PTR_H_
#define COSMOPOLITAN_CTL_UNIQUE_PTR_H_
#include <__utility/forward.h>
#include <__utility/move.h>
#include <__utility/swap.h>
#include "utility.h"
namespace ctl {
@ -36,11 +34,11 @@ struct unique_ptr
}
constexpr unique_ptr(pointer p, auto&& d) noexcept
: p(p), d(std::forward<decltype(d)>(d))
: p(p), d(ctl::forward<decltype(d)>(d))
{
}
constexpr unique_ptr(unique_ptr&& u) noexcept : p(u.p), d(std::move(u.d))
constexpr unique_ptr(unique_ptr&& u) noexcept : p(u.p), d(ctl::move(u.d))
{
u.p = nullptr;
}
@ -89,7 +87,7 @@ struct unique_ptr
inline void swap(unique_ptr& r) noexcept
{
using std::swap;
using ctl::swap;
swap(p, r.p);
swap(d, r.d);
}
@ -115,7 +113,7 @@ struct unique_ptr
}
inline element_type& operator*() const
noexcept(noexcept(*std::declval<pointer>()))
noexcept(noexcept(*ctl::declval<pointer>()))
{
if (!p)
__builtin_trap();
@ -134,7 +132,7 @@ template<typename T, typename... Args>
inline unique_ptr<T>
make_unique(Args&&... args)
{
return unique_ptr<T>(new T(std::forward<Args>(args)...));
return unique_ptr<T>(new T(ctl::forward<Args>(args)...));
}
template<typename T>

19
ctl/utility.cc Normal file
View file

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

61
ctl/utility.h Normal file
View file

@ -0,0 +1,61 @@
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
#ifndef COSMOPOLITAN_CTL_UTILITY_H_
#define COSMOPOLITAN_CTL_UTILITY_H_
namespace ctl {
namespace __ {
template<typename T>
struct no_infer_
{
typedef T type;
};
template<typename T>
using no_infer = typename no_infer_<T>::type;
} // namespace __
template<typename T>
constexpr T&&
move(T& t) noexcept
{
return static_cast<T&&>(t);
}
template<typename T>
constexpr T&&
forward(__::no_infer<T>& t) noexcept
{
return static_cast<T&&>(t);
}
template<typename T>
// TODO(mrdomino): requires move_constructible<T> && move_assignable<T>
constexpr void
swap(T& a, T& b) noexcept
{
T t(ctl::move(a));
a = ctl::move(b);
b = ctl::move(t);
}
template<typename T, size_t N>
// TODO(mrdomino): requires is_swappable
constexpr void
swap(T (&a)[N], T (&b)[N]) noexcept
{
for (size_t i = 0; i < N; ++i) {
swap(a[i], b[i]);
}
}
template<typename T>
T&&
declval() noexcept;
} // namespace ctl
#endif // COSMOPOLITAN_CTL_UTILITY_H_

View file

@ -3,9 +3,7 @@
#ifndef COSMOPOLITAN_CTL_OPTIONAL_H_
#define COSMOPOLITAN_CTL_OPTIONAL_H_
#include "new.h"
#include <__utility/forward.h>
#include <__utility/move.h>
#include <__utility/swap.h>
#include "utility.h"
namespace ctl {
@ -173,7 +171,7 @@ struct vector
return;
T* newP = new T[c2];
for (size_t i = 0; i < n; ++i)
newP[i] = std::move(p[i]);
newP[i] = ctl::move(p[i]);
delete[] p;
p = newP;
c = c2;
@ -197,7 +195,7 @@ struct vector
c2 += c2 >> 1;
reserve(c2);
}
new (&p[n]) T(std::forward<T>(e));
new (&p[n]) T(ctl::forward<T>(e));
++n;
}
@ -209,7 +207,7 @@ struct vector
c2 += c2 >> 1;
reserve(c2);
}
new (&p[n]) T(std::forward<Args>(args)...);
new (&p[n]) T(ctl::forward<Args>(args)...);
++n;
}
@ -236,9 +234,9 @@ struct vector
void swap(vector& other) noexcept
{
std::swap(n, other.n);
std::swap(c, other.c);
std::swap(p, other.p);
ctl::swap(n, other.n);
ctl::swap(c, other.c);
ctl::swap(p, other.p);
}
};

View file

@ -39,3 +39,5 @@ struct __cxx_choose_expr<false, _T, _U> {
/* todo jart whyyyy */
#define _Float16 __fp16
#endif
using nullptr_t = decltype(nullptr);

View file

@ -63,7 +63,7 @@ main()
{
ctl::optional<ctl::string> x("world");
ctl::optional<ctl::string> y(std::move(x));
ctl::optional<ctl::string> y(ctl::move(x));
if (!y)
return 9;
if (!y.has_value())
@ -87,7 +87,7 @@ main()
{
ctl::optional<ctl::string> x("hello");
ctl::optional<ctl::string> y;
y = std::move(x);
y = ctl::move(x);
if (!y)
return 16;
if (!y.has_value())

View file

@ -19,7 +19,6 @@
#include "ctl/string.h"
#include <__type_traits/is_same.h>
#include <__utility/move.h>
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
@ -211,7 +210,7 @@ main()
{
String s = "hello";
String s2 = std::move(s);
String s2 = ctl::move(s);
if (s2 != "hello")
return 47;
if (!s.empty())

View file

@ -18,8 +18,6 @@
#include "ctl/string_view.h"
#include <__utility/move.h>
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
@ -90,7 +88,7 @@ main(int argc, char* argv[])
{
ctl::string_view s = "hello";
ctl::string_view s2 = std::move(s);
ctl::string_view s2 = ctl::move(s);
if (s2 != "hello")
return 16;
if (s.empty())

View file

@ -18,7 +18,7 @@
#include "ctl/unique_ptr.h"
#include <type_traits>
#include <__type_traits/is_same.h>
#include "libc/runtime/runtime.h"
@ -32,7 +32,7 @@ template<typename T, typename... Args>
Ptr<T>
Mk(Args&&... args)
{
return ctl::make_unique<T, Args...>(std::forward<Args>(args)...);
return ctl::make_unique<T, Args...>(ctl::forward<Args>(args)...);
}
template<typename T>
@ -161,7 +161,7 @@ main()
// shouldn't compile
x = y;
#endif
x = std::move(y);
x = ctl::move(y);
if (g != 1)
return 10;
if (y)

View file

@ -50,7 +50,7 @@ main()
ctl::string yo = "foo";
ctl::vector<ctl::string> A;
A.push_back("fun");
A.push_back(std::move(yo));
A.push_back(ctl::move(yo));
if (yo != "")
return 5;
A.emplace_back("bar");
@ -94,7 +94,7 @@ main()
A.push_back(1);
A.push_back(2);
A.push_back(3);
ctl::vector<int> B(std::move(A));
ctl::vector<int> B(ctl::move(A));
if (A.size() != 0)
return 17;
if (B.size() != 3)
@ -122,7 +122,7 @@ main()
A.push_back(2);
A.push_back(3);
ctl::vector<int> B;
B = std::move(A);
B = ctl::move(A);
if (A.size() != 0)
return 22;
if (B.size() != 3)
@ -286,7 +286,7 @@ main()
A.push_back(2);
A.push_back(3);
ctl::vector<int> B;
B = std::move(A);
B = ctl::move(A);
if (A.size() != 0)
return 63;
if (B.size() != 3)