Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Own<T> uniquely owned heap pointer #79

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ add_library(subspace STATIC
"num/__private/signed_integer_macros.h"
"num/__private/unsigned_integer_macros.h"
"num/float.h"
"num/float_concepts.h"
"num/fp_category.h"
"num/signed_integer.h"
"num/integer_concepts.h"
Expand All @@ -81,6 +82,7 @@ add_library(subspace STATIC
"option/__private/storage.h"
"option/option.h"
"option/state.h"
"ptr/own.h"
"result/__private/is_result_type.h"
"result/result.h"
"tuple/__private/storage.h"
Expand Down Expand Up @@ -136,6 +138,7 @@ add_executable(subspace_unittests
"num/usize_unittest.cc"
"option/option_unittest.cc"
"option/option_types_unittest.cc"
"ptr/own_unittest.cc"
"result/result_unittest.cc"
"result/result_types_unittest.cc"
"tuple/tuple_unittest.cc"
Expand Down
25 changes: 14 additions & 11 deletions construct/make_default.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,17 @@ namespace sus::construct {
namespace __private {

template <class T>
constexpr inline bool has_with_default(...) {
return false;
}

template <class T, class... Args>
requires(std::same_as<decltype(T::with_default(std::declval<Args>()...)), T>)
constexpr inline bool has_with_default(int) {
return true;
}
concept HasWithDefault = requires {
{ T::with_default() } -> std::same_as<T>;
};

} // namespace __private

// clang-format off
template <class T>
concept MakeDefault =
(std::constructible_from<T> && !__private::has_with_default<T>(0)) ||
(!std::constructible_from<T> && __private::has_with_default<T>(0));
(std::constructible_from<T> && !__private::HasWithDefault<T>) ||
(!std::constructible_from<T> && __private::HasWithDefault<T>);
// clang-format on

template <MakeDefault T>
Expand All @@ -48,4 +42,13 @@ inline constexpr T make_default() noexcept {
return T::with_default();
}

template <MakeDefault T>
requires(std::is_move_constructible_v<T>)
inline T* alloc_make_default() noexcept {
if constexpr (std::constructible_from<T>)
return new T();
else
return new T(T::with_default());
}

} // namespace sus::construct
33 changes: 33 additions & 0 deletions num/float_concepts.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <concepts>

namespace sus::num {

struct f32;
struct f64;

template <class T>
concept FloatingPoint =
std::same_as<f32, std::decay_t<T>> || std::same_as<f64, std::decay_t<T>>;

template <class T>
concept PrimitiveFloatingPoint =
std::same_as<float, T> ||
std::same_as<double, T> || std::same_as<long double, T>;

} // namespace sus::num
14 changes: 14 additions & 0 deletions num/unsigned_integer.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include <stdint.h>

#include "marker/unsafe.h"
#include "num/__private/unsigned_integer_macros.h"

namespace sus::num {
Expand Down Expand Up @@ -98,6 +99,19 @@ struct usize final {
check(val <= uint64_t{MAX_PRIMITIVE});
}
}

// Constructs a `usize` from a pointer type.
template <class T>
static inline usize from_ptr(::sus::marker::UnsafeFnMarker, T* t) {
return reinterpret_cast<decltype(std::declval<usize>().primitive_value)>(t);
}

// Converts a `usize` into a pointer type.
template <class T>
requires(std::is_pointer_v<T>)
inline T to_ptr(::sus::marker::UnsafeFnMarker) const {
return reinterpret_cast<T>(primitive_value);
}
};

} // namespace sus::num
Expand Down
4 changes: 2 additions & 2 deletions option/option.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,10 @@ class Option final {
///
/// The Option's contained type `T` must be #MakeDefault, and will be
/// constructed through that trait.
static inline constexpr Option<T> with_default() noexcept
static inline constexpr Option with_default() noexcept
requires(::sus::construct::MakeDefault<T>)
{
return Option<T>(::sus::construct::make_default<T>());
return Option(::sus::construct::make_default<T>());
}

/// Destructor for the Option.
Expand Down
59 changes: 59 additions & 0 deletions ptr/__private/in_use.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "macros/always_inline.h"
#include "mem/relocate.h"
#include "ptr/ptr_concepts.h"

namespace sus::ptr {
template <class T>
class [[sus_trivial_abi]] Own;
}

namespace sus::ptr::__private {

template <class T>
class InUse {
public:
constexpr sus_always_inline ~InUse() noexcept { own.t_ = &t; }

constexpr sus_always_inline const auto* operator->() const&& noexcept
requires(HasArrow<T>)
{
return t.operator->();
}
constexpr sus_always_inline auto* operator->() && noexcept
requires(HasArrowMut<T>)
{
return t.operator->();
}

constexpr sus_always_inline const auto* operator->() const&& noexcept
requires(!HasArrowMut<T>)
{
return &t;
}
constexpr sus_always_inline auto* operator->() && noexcept
requires(!HasArrowMut<T>)
{
return &t;
}

T& t;
Own<T>& own;
};

} // namespace sus::ptr::__private
Loading