blob: a021ca7447f8dc5fff4ece79670e4147a7a6e2a2 [file] [log] [blame]
David Tolnay7db73692019-10-20 14:51:12 -04001#pragma once
2#include <array>
3#include <cstdint>
David Tolnayb7a7cb62020-03-17 21:18:40 -07004#include <exception>
David Tolnay001102a2020-03-01 20:05:04 -08005#include <iosfwd>
David Tolnay7db73692019-10-20 14:51:12 -04006#include <string>
David Tolnayf6292372020-03-01 21:09:11 -08007#include <type_traits>
David Tolnay7db73692019-10-20 14:51:12 -04008
David Tolnay750755e2020-03-01 13:04:08 -08009namespace rust {
David Tolnay8c730492020-03-13 01:29:06 -070010inline namespace cxxbridge02 {
David Tolnay7db73692019-10-20 14:51:12 -040011
David Tolnayd1e2efc2020-03-03 22:25:43 -080012struct unsafe_bitcopy_t;
13
David Tolnayb7a7cb62020-03-17 21:18:40 -070014#ifndef CXXBRIDGE02_RUST_STRING
15#define CXXBRIDGE02_RUST_STRING
David Tolnay56082162020-03-01 12:57:33 -080016class String final {
David Tolnay7db73692019-10-20 14:51:12 -040017public:
David Tolnay56082162020-03-01 12:57:33 -080018 String() noexcept;
David Tolnayd9c4ac92020-03-01 20:33:58 -080019 String(const String &) noexcept;
20 String(String &&) noexcept;
David Tolnay56082162020-03-01 12:57:33 -080021 ~String() noexcept;
David Tolnayd9c4ac92020-03-01 20:33:58 -080022
23 String(const std::string &);
24 String(const char *);
25
26 String &operator=(const String &) noexcept;
27 String &operator=(String &&) noexcept;
28
David Tolnay404d6892020-03-01 20:19:41 -080029 explicit operator std::string() const;
David Tolnay7db73692019-10-20 14:51:12 -040030
31 // Note: no null terminator.
32 const char *data() const noexcept;
33 size_t size() const noexcept;
34 size_t length() const noexcept;
35
David Tolnayd1e2efc2020-03-03 22:25:43 -080036 // Internal API only intended for the cxxbridge code generator.
37 String(unsafe_bitcopy_t, const String &) noexcept;
38
David Tolnay7db73692019-10-20 14:51:12 -040039private:
40 // Size and alignment statically verified by rust_string.rs.
41 std::array<uintptr_t, 3> repr;
42};
David Tolnayb7a7cb62020-03-17 21:18:40 -070043#endif // CXXBRIDGE02_RUST_STRING
David Tolnay7db73692019-10-20 14:51:12 -040044
David Tolnayb7a7cb62020-03-17 21:18:40 -070045#ifndef CXXBRIDGE02_RUST_STR
46#define CXXBRIDGE02_RUST_STR
David Tolnay09dbe752020-03-01 13:00:40 -080047class Str final {
David Tolnay7db73692019-10-20 14:51:12 -040048public:
David Tolnay09dbe752020-03-01 13:00:40 -080049 Str() noexcept;
David Tolnayd9c4ac92020-03-01 20:33:58 -080050 Str(const Str &) noexcept;
51
David Tolnay851677c2020-03-01 23:49:46 -080052 Str(const std::string &);
53 Str(const char *);
54 Str(std::string &&) = delete;
David Tolnayd9c4ac92020-03-01 20:33:58 -080055
56 Str &operator=(Str) noexcept;
57
David Tolnay404d6892020-03-01 20:19:41 -080058 explicit operator std::string() const;
David Tolnay7db73692019-10-20 14:51:12 -040059
60 // Note: no null terminator.
61 const char *data() const noexcept;
62 size_t size() const noexcept;
63 size_t length() const noexcept;
64
65 // Repr is PRIVATE; must not be used other than by our generated code.
66 //
67 // Not necessarily ABI compatible with &str. Codegen will translate to
68 // cxx::rust_str::RustStr which matches this layout.
69 struct Repr {
70 const char *ptr;
71 size_t len;
72 };
David Tolnayd9c4ac92020-03-01 20:33:58 -080073 Str(Repr) noexcept;
David Tolnaybaae4432020-03-01 20:20:10 -080074 explicit operator Repr() noexcept;
David Tolnay7db73692019-10-20 14:51:12 -040075
76private:
77 Repr repr;
78};
David Tolnayb7a7cb62020-03-17 21:18:40 -070079#endif // CXXBRIDGE02_RUST_STR
David Tolnay7db73692019-10-20 14:51:12 -040080
David Tolnay8c730492020-03-13 01:29:06 -070081#ifndef CXXBRIDGE02_RUST_BOX
82#define CXXBRIDGE02_RUST_BOX
David Tolnay324437a2020-03-01 13:02:24 -080083template <typename T> class Box final {
David Tolnay7db73692019-10-20 14:51:12 -040084public:
David Tolnayf6292372020-03-01 21:09:11 -080085 using value_type = T;
David Tolnay9f921372020-03-01 21:09:25 -080086 using const_pointer = typename std::add_pointer<
87 typename std::add_const<value_type>::type>::type;
88 using pointer = typename std::add_pointer<value_type>::type;
David Tolnayf6292372020-03-01 21:09:11 -080089
David Tolnay324437a2020-03-01 13:02:24 -080090 Box(const Box &other) : Box(*other) {}
David Tolnay33169bd2020-03-06 13:02:08 -080091 Box(Box &&other) noexcept : ptr(other.ptr) { other.ptr = nullptr; }
David Tolnay324437a2020-03-01 13:02:24 -080092 Box(const T &val) {
David Tolnay7db73692019-10-20 14:51:12 -040093 this->uninit();
David Tolnay33169bd2020-03-06 13:02:08 -080094 ::new (this->ptr) T(val);
David Tolnay7db73692019-10-20 14:51:12 -040095 }
David Tolnay324437a2020-03-01 13:02:24 -080096 Box &operator=(const Box &other) {
David Tolnay7db73692019-10-20 14:51:12 -040097 if (this != &other) {
David Tolnay33169bd2020-03-06 13:02:08 -080098 if (this->ptr) {
David Tolnay7db73692019-10-20 14:51:12 -040099 **this = *other;
100 } else {
101 this->uninit();
David Tolnay33169bd2020-03-06 13:02:08 -0800102 ::new (this->ptr) T(*other);
David Tolnay7db73692019-10-20 14:51:12 -0400103 }
104 }
105 return *this;
106 }
David Tolnay324437a2020-03-01 13:02:24 -0800107 Box &operator=(Box &&other) noexcept {
David Tolnay33169bd2020-03-06 13:02:08 -0800108 if (this->ptr) {
David Tolnay7db73692019-10-20 14:51:12 -0400109 this->drop();
110 }
David Tolnay33169bd2020-03-06 13:02:08 -0800111 this->ptr = other.ptr;
112 other.ptr = nullptr;
David Tolnay7db73692019-10-20 14:51:12 -0400113 return *this;
114 }
David Tolnay324437a2020-03-01 13:02:24 -0800115 ~Box() noexcept {
David Tolnay33169bd2020-03-06 13:02:08 -0800116 if (this->ptr) {
David Tolnay7db73692019-10-20 14:51:12 -0400117 this->drop();
118 }
119 }
120
David Tolnay33169bd2020-03-06 13:02:08 -0800121 const T *operator->() const noexcept { return this->ptr; }
122 const T &operator*() const noexcept { return *this->ptr; }
123 T *operator->() noexcept { return this->ptr; }
124 T &operator*() noexcept { return *this->ptr; }
David Tolnay7db73692019-10-20 14:51:12 -0400125
126 // Important: requires that `raw` came from an into_raw call. Do not pass a
127 // pointer from `new` or any other source.
David Tolnay324437a2020-03-01 13:02:24 -0800128 static Box from_raw(T *raw) noexcept {
129 Box box;
David Tolnay33169bd2020-03-06 13:02:08 -0800130 box.ptr = raw;
David Tolnay7db73692019-10-20 14:51:12 -0400131 return box;
132 }
133
134 T *into_raw() noexcept {
David Tolnay33169bd2020-03-06 13:02:08 -0800135 T *raw = this->ptr;
136 this->ptr = nullptr;
David Tolnay7db73692019-10-20 14:51:12 -0400137 return raw;
138 }
139
140private:
David Tolnay324437a2020-03-01 13:02:24 -0800141 Box() noexcept {}
David Tolnay7db73692019-10-20 14:51:12 -0400142 void uninit() noexcept;
David Tolnay7db73692019-10-20 14:51:12 -0400143 void drop() noexcept;
David Tolnay33169bd2020-03-06 13:02:08 -0800144 T *ptr;
David Tolnay7db73692019-10-20 14:51:12 -0400145};
David Tolnay8c730492020-03-13 01:29:06 -0700146#endif // CXXBRIDGE02_RUST_BOX
David Tolnay7db73692019-10-20 14:51:12 -0400147
David Tolnayb7a7cb62020-03-17 21:18:40 -0700148#ifndef CXXBRIDGE02_RUST_ERROR
149#define CXXBRIDGE02_RUST_ERROR
David Tolnay1e548172020-03-16 13:37:09 -0700150class Error final : std::exception {
151public:
152 Error(const Error &);
153 Error(Error &&) noexcept;
154 Error(Str::Repr) noexcept;
155 ~Error() noexcept;
156 const char *what() const noexcept override;
157
158private:
159 Str::Repr msg;
160};
David Tolnayb7a7cb62020-03-17 21:18:40 -0700161#endif // CXXBRIDGE02_RUST_ERROR
David Tolnay1e548172020-03-16 13:37:09 -0700162
David Tolnay851677c2020-03-01 23:49:46 -0800163std::ostream &operator<<(std::ostream &, const String &);
164std::ostream &operator<<(std::ostream &, const Str &);
David Tolnay7db73692019-10-20 14:51:12 -0400165
David Tolnay3b0c9882020-03-01 14:08:57 -0800166// Snake case aliases for use in code that uses this style for type names.
167using string = String;
168using str = Str;
169template <class T> using box = Box<T>;
David Tolnay1e548172020-03-16 13:37:09 -0700170using error = Error;
David Tolnay3b0c9882020-03-01 14:08:57 -0800171
David Tolnayb7a7cb62020-03-17 21:18:40 -0700172#ifndef CXXBRIDGE02_RUST_BITCOPY
173#define CXXBRIDGE02_RUST_BITCOPY
David Tolnayd1e2efc2020-03-03 22:25:43 -0800174struct unsafe_bitcopy_t {
175 explicit unsafe_bitcopy_t() = default;
176};
177constexpr unsafe_bitcopy_t unsafe_bitcopy{};
David Tolnayb7a7cb62020-03-17 21:18:40 -0700178#endif // CXXBRIDGE02_RUST_BITCOPY
David Tolnayd1e2efc2020-03-03 22:25:43 -0800179
David Tolnay8c730492020-03-13 01:29:06 -0700180} // namespace cxxbridge02
David Tolnay750755e2020-03-01 13:04:08 -0800181} // namespace rust