mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
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:
parent
a795017416
commit
9a5a13854d
13 changed files with 117 additions and 46 deletions
|
@ -3,9 +3,7 @@
|
||||||
#ifndef COSMOPOLITAN_CTL_OPTIONAL_H_
|
#ifndef COSMOPOLITAN_CTL_OPTIONAL_H_
|
||||||
#define COSMOPOLITAN_CTL_OPTIONAL_H_
|
#define COSMOPOLITAN_CTL_OPTIONAL_H_
|
||||||
#include "new.h"
|
#include "new.h"
|
||||||
#include <__utility/forward.h>
|
#include "utility.h"
|
||||||
#include <__utility/move.h>
|
|
||||||
#include <__utility/swap.h>
|
|
||||||
|
|
||||||
namespace ctl {
|
namespace ctl {
|
||||||
|
|
||||||
|
@ -32,7 +30,7 @@ class optional
|
||||||
|
|
||||||
optional(T&& value) : present_(true)
|
optional(T&& value) : present_(true)
|
||||||
{
|
{
|
||||||
new (&value_) T(std::move(value));
|
new (&value_) T(ctl::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
optional(const optional& other) : present_(other.present_)
|
optional(const optional& other) : present_(other.present_)
|
||||||
|
@ -44,7 +42,7 @@ class optional
|
||||||
optional(optional&& other) noexcept : present_(other.present_)
|
optional(optional&& other) noexcept : present_(other.present_)
|
||||||
{
|
{
|
||||||
if (other.present_)
|
if (other.present_)
|
||||||
new (&value_) T(std::move(other.value_));
|
new (&value_) T(ctl::move(other.value_));
|
||||||
}
|
}
|
||||||
|
|
||||||
optional& operator=(const optional& other)
|
optional& operator=(const optional& other)
|
||||||
|
@ -63,7 +61,7 @@ class optional
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
reset();
|
reset();
|
||||||
if (other.present_)
|
if (other.present_)
|
||||||
new (&value_) T(std::move(other.value_));
|
new (&value_) T(ctl::move(other.value_));
|
||||||
present_ = other.present_;
|
present_ = other.present_;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -87,7 +85,7 @@ class optional
|
||||||
{
|
{
|
||||||
if (!present_)
|
if (!present_)
|
||||||
__builtin_trap();
|
__builtin_trap();
|
||||||
return std::move(value_);
|
return ctl::move(value_);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit operator bool() const noexcept
|
explicit operator bool() const noexcept
|
||||||
|
@ -113,19 +111,19 @@ class optional
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
present_ = true;
|
present_ = true;
|
||||||
new (&value_) T(std::forward<Args>(args)...);
|
new (&value_) T(ctl::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(optional& other) noexcept
|
void swap(optional& other) noexcept
|
||||||
{
|
{
|
||||||
using std::swap;
|
using ctl::swap;
|
||||||
if (present_ && other.present_) {
|
if (present_ && other.present_) {
|
||||||
swap(value_, other.value_);
|
swap(value_, other.value_);
|
||||||
} else if (present_) {
|
} else if (present_) {
|
||||||
other.emplace(std::move(value_));
|
other.emplace(ctl::move(value_));
|
||||||
reset();
|
reset();
|
||||||
} else if (other.present_) {
|
} else if (other.present_) {
|
||||||
emplace(std::move(other.value_));
|
emplace(ctl::move(other.value_));
|
||||||
other.reset();
|
other.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,10 +87,7 @@ class string
|
||||||
|
|
||||||
void swap(string& s) noexcept
|
void swap(string& s) noexcept
|
||||||
{
|
{
|
||||||
char tmp[__::string_size];
|
ctl::swap(blob, s.blob);
|
||||||
__builtin_memcpy(tmp, blob, __::string_size);
|
|
||||||
__builtin_memcpy(blob, s.blob, __::string_size);
|
|
||||||
__builtin_memcpy(s.blob, tmp, __::string_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string(string&& s) noexcept
|
string(string&& s) noexcept
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
|
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
|
||||||
#ifndef COSMOPOLITAN_CTL_STRINGVIEW_H_
|
#ifndef COSMOPOLITAN_CTL_STRINGVIEW_H_
|
||||||
#define COSMOPOLITAN_CTL_STRINGVIEW_H_
|
#define COSMOPOLITAN_CTL_STRINGVIEW_H_
|
||||||
|
#include "utility.h"
|
||||||
|
|
||||||
namespace ctl {
|
namespace ctl {
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
|
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
|
||||||
#ifndef COSMOPOLITAN_CTL_UNIQUE_PTR_H_
|
#ifndef COSMOPOLITAN_CTL_UNIQUE_PTR_H_
|
||||||
#define COSMOPOLITAN_CTL_UNIQUE_PTR_H_
|
#define COSMOPOLITAN_CTL_UNIQUE_PTR_H_
|
||||||
#include <__utility/forward.h>
|
#include "utility.h"
|
||||||
#include <__utility/move.h>
|
|
||||||
#include <__utility/swap.h>
|
|
||||||
|
|
||||||
namespace ctl {
|
namespace ctl {
|
||||||
|
|
||||||
|
@ -36,11 +34,11 @@ struct unique_ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr unique_ptr(pointer p, auto&& d) noexcept
|
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;
|
u.p = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +87,7 @@ struct unique_ptr
|
||||||
|
|
||||||
inline void swap(unique_ptr& r) noexcept
|
inline void swap(unique_ptr& r) noexcept
|
||||||
{
|
{
|
||||||
using std::swap;
|
using ctl::swap;
|
||||||
swap(p, r.p);
|
swap(p, r.p);
|
||||||
swap(d, r.d);
|
swap(d, r.d);
|
||||||
}
|
}
|
||||||
|
@ -115,7 +113,7 @@ struct unique_ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
inline element_type& operator*() const
|
inline element_type& operator*() const
|
||||||
noexcept(noexcept(*std::declval<pointer>()))
|
noexcept(noexcept(*ctl::declval<pointer>()))
|
||||||
{
|
{
|
||||||
if (!p)
|
if (!p)
|
||||||
__builtin_trap();
|
__builtin_trap();
|
||||||
|
@ -134,7 +132,7 @@ template<typename T, typename... Args>
|
||||||
inline unique_ptr<T>
|
inline unique_ptr<T>
|
||||||
make_unique(Args&&... args)
|
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>
|
template<typename T>
|
||||||
|
|
19
ctl/utility.cc
Normal file
19
ctl/utility.cc
Normal 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
61
ctl/utility.h
Normal 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_
|
16
ctl/vector.h
16
ctl/vector.h
|
@ -3,9 +3,7 @@
|
||||||
#ifndef COSMOPOLITAN_CTL_OPTIONAL_H_
|
#ifndef COSMOPOLITAN_CTL_OPTIONAL_H_
|
||||||
#define COSMOPOLITAN_CTL_OPTIONAL_H_
|
#define COSMOPOLITAN_CTL_OPTIONAL_H_
|
||||||
#include "new.h"
|
#include "new.h"
|
||||||
#include <__utility/forward.h>
|
#include "utility.h"
|
||||||
#include <__utility/move.h>
|
|
||||||
#include <__utility/swap.h>
|
|
||||||
|
|
||||||
namespace ctl {
|
namespace ctl {
|
||||||
|
|
||||||
|
@ -173,7 +171,7 @@ struct vector
|
||||||
return;
|
return;
|
||||||
T* newP = new T[c2];
|
T* newP = new T[c2];
|
||||||
for (size_t i = 0; i < n; ++i)
|
for (size_t i = 0; i < n; ++i)
|
||||||
newP[i] = std::move(p[i]);
|
newP[i] = ctl::move(p[i]);
|
||||||
delete[] p;
|
delete[] p;
|
||||||
p = newP;
|
p = newP;
|
||||||
c = c2;
|
c = c2;
|
||||||
|
@ -197,7 +195,7 @@ struct vector
|
||||||
c2 += c2 >> 1;
|
c2 += c2 >> 1;
|
||||||
reserve(c2);
|
reserve(c2);
|
||||||
}
|
}
|
||||||
new (&p[n]) T(std::forward<T>(e));
|
new (&p[n]) T(ctl::forward<T>(e));
|
||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +207,7 @@ struct vector
|
||||||
c2 += c2 >> 1;
|
c2 += c2 >> 1;
|
||||||
reserve(c2);
|
reserve(c2);
|
||||||
}
|
}
|
||||||
new (&p[n]) T(std::forward<Args>(args)...);
|
new (&p[n]) T(ctl::forward<Args>(args)...);
|
||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,9 +234,9 @@ struct vector
|
||||||
|
|
||||||
void swap(vector& other) noexcept
|
void swap(vector& other) noexcept
|
||||||
{
|
{
|
||||||
std::swap(n, other.n);
|
ctl::swap(n, other.n);
|
||||||
std::swap(c, other.c);
|
ctl::swap(c, other.c);
|
||||||
std::swap(p, other.p);
|
ctl::swap(p, other.p);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,3 +39,5 @@ struct __cxx_choose_expr<false, _T, _U> {
|
||||||
/* todo jart whyyyy */
|
/* todo jart whyyyy */
|
||||||
#define _Float16 __fp16
|
#define _Float16 __fp16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
using nullptr_t = decltype(nullptr);
|
||||||
|
|
|
@ -63,7 +63,7 @@ main()
|
||||||
|
|
||||||
{
|
{
|
||||||
ctl::optional<ctl::string> x("world");
|
ctl::optional<ctl::string> x("world");
|
||||||
ctl::optional<ctl::string> y(std::move(x));
|
ctl::optional<ctl::string> y(ctl::move(x));
|
||||||
if (!y)
|
if (!y)
|
||||||
return 9;
|
return 9;
|
||||||
if (!y.has_value())
|
if (!y.has_value())
|
||||||
|
@ -87,7 +87,7 @@ main()
|
||||||
{
|
{
|
||||||
ctl::optional<ctl::string> x("hello");
|
ctl::optional<ctl::string> x("hello");
|
||||||
ctl::optional<ctl::string> y;
|
ctl::optional<ctl::string> y;
|
||||||
y = std::move(x);
|
y = ctl::move(x);
|
||||||
if (!y)
|
if (!y)
|
||||||
return 16;
|
return 16;
|
||||||
if (!y.has_value())
|
if (!y.has_value())
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include "ctl/string.h"
|
#include "ctl/string.h"
|
||||||
|
|
||||||
#include <__type_traits/is_same.h>
|
#include <__type_traits/is_same.h>
|
||||||
#include <__utility/move.h>
|
|
||||||
|
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
@ -211,7 +210,7 @@ main()
|
||||||
|
|
||||||
{
|
{
|
||||||
String s = "hello";
|
String s = "hello";
|
||||||
String s2 = std::move(s);
|
String s2 = ctl::move(s);
|
||||||
if (s2 != "hello")
|
if (s2 != "hello")
|
||||||
return 47;
|
return 47;
|
||||||
if (!s.empty())
|
if (!s.empty())
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
|
|
||||||
#include "ctl/string_view.h"
|
#include "ctl/string_view.h"
|
||||||
|
|
||||||
#include <__utility/move.h>
|
|
||||||
|
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
|
@ -90,7 +88,7 @@ main(int argc, char* argv[])
|
||||||
|
|
||||||
{
|
{
|
||||||
ctl::string_view s = "hello";
|
ctl::string_view s = "hello";
|
||||||
ctl::string_view s2 = std::move(s);
|
ctl::string_view s2 = ctl::move(s);
|
||||||
if (s2 != "hello")
|
if (s2 != "hello")
|
||||||
return 16;
|
return 16;
|
||||||
if (s.empty())
|
if (s.empty())
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#include "ctl/unique_ptr.h"
|
#include "ctl/unique_ptr.h"
|
||||||
|
|
||||||
#include <type_traits>
|
#include <__type_traits/is_same.h>
|
||||||
|
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ template<typename T, typename... Args>
|
||||||
Ptr<T>
|
Ptr<T>
|
||||||
Mk(Args&&... args)
|
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>
|
template<typename T>
|
||||||
|
@ -161,7 +161,7 @@ main()
|
||||||
// shouldn't compile
|
// shouldn't compile
|
||||||
x = y;
|
x = y;
|
||||||
#endif
|
#endif
|
||||||
x = std::move(y);
|
x = ctl::move(y);
|
||||||
if (g != 1)
|
if (g != 1)
|
||||||
return 10;
|
return 10;
|
||||||
if (y)
|
if (y)
|
||||||
|
|
|
@ -50,7 +50,7 @@ main()
|
||||||
ctl::string yo = "foo";
|
ctl::string yo = "foo";
|
||||||
ctl::vector<ctl::string> A;
|
ctl::vector<ctl::string> A;
|
||||||
A.push_back("fun");
|
A.push_back("fun");
|
||||||
A.push_back(std::move(yo));
|
A.push_back(ctl::move(yo));
|
||||||
if (yo != "")
|
if (yo != "")
|
||||||
return 5;
|
return 5;
|
||||||
A.emplace_back("bar");
|
A.emplace_back("bar");
|
||||||
|
@ -94,7 +94,7 @@ main()
|
||||||
A.push_back(1);
|
A.push_back(1);
|
||||||
A.push_back(2);
|
A.push_back(2);
|
||||||
A.push_back(3);
|
A.push_back(3);
|
||||||
ctl::vector<int> B(std::move(A));
|
ctl::vector<int> B(ctl::move(A));
|
||||||
if (A.size() != 0)
|
if (A.size() != 0)
|
||||||
return 17;
|
return 17;
|
||||||
if (B.size() != 3)
|
if (B.size() != 3)
|
||||||
|
@ -122,7 +122,7 @@ main()
|
||||||
A.push_back(2);
|
A.push_back(2);
|
||||||
A.push_back(3);
|
A.push_back(3);
|
||||||
ctl::vector<int> B;
|
ctl::vector<int> B;
|
||||||
B = std::move(A);
|
B = ctl::move(A);
|
||||||
if (A.size() != 0)
|
if (A.size() != 0)
|
||||||
return 22;
|
return 22;
|
||||||
if (B.size() != 3)
|
if (B.size() != 3)
|
||||||
|
@ -286,7 +286,7 @@ main()
|
||||||
A.push_back(2);
|
A.push_back(2);
|
||||||
A.push_back(3);
|
A.push_back(3);
|
||||||
ctl::vector<int> B;
|
ctl::vector<int> B;
|
||||||
B = std::move(A);
|
B = ctl::move(A);
|
||||||
if (A.size() != 0)
|
if (A.size() != 0)
|
||||||
return 63;
|
return 63;
|
||||||
if (B.size() != 3)
|
if (B.size() != 3)
|
||||||
|
|
Loading…
Reference in a new issue