133d722a9Sopenharmony_ciuse crate::gen::block::Block;
233d722a9Sopenharmony_ciuse crate::gen::ifndef;
333d722a9Sopenharmony_ciuse crate::gen::out::{Content, OutFile};
433d722a9Sopenharmony_ci
533d722a9Sopenharmony_ci#[derive(Default, PartialEq)]
633d722a9Sopenharmony_cipub struct Builtins<'a> {
733d722a9Sopenharmony_ci    pub panic: bool,
833d722a9Sopenharmony_ci    pub rust_string: bool,
933d722a9Sopenharmony_ci    pub rust_str: bool,
1033d722a9Sopenharmony_ci    pub rust_slice: bool,
1133d722a9Sopenharmony_ci    pub rust_box: bool,
1233d722a9Sopenharmony_ci    pub rust_vec: bool,
1333d722a9Sopenharmony_ci    pub rust_fn: bool,
1433d722a9Sopenharmony_ci    pub rust_isize: bool,
1533d722a9Sopenharmony_ci    pub opaque: bool,
1633d722a9Sopenharmony_ci    pub layout: bool,
1733d722a9Sopenharmony_ci    pub unsafe_bitcopy: bool,
1833d722a9Sopenharmony_ci    pub unsafe_bitcopy_t: bool,
1933d722a9Sopenharmony_ci    pub rust_error: bool,
2033d722a9Sopenharmony_ci    pub manually_drop: bool,
2133d722a9Sopenharmony_ci    pub maybe_uninit: bool,
2233d722a9Sopenharmony_ci    pub trycatch: bool,
2333d722a9Sopenharmony_ci    pub ptr_len: bool,
2433d722a9Sopenharmony_ci    pub repr_fat: bool,
2533d722a9Sopenharmony_ci    pub rust_str_new_unchecked: bool,
2633d722a9Sopenharmony_ci    pub rust_str_repr: bool,
2733d722a9Sopenharmony_ci    pub rust_slice_new: bool,
2833d722a9Sopenharmony_ci    pub rust_slice_repr: bool,
2933d722a9Sopenharmony_ci    pub relocatable: bool,
3033d722a9Sopenharmony_ci    pub relocatable_or_array: bool,
3133d722a9Sopenharmony_ci    pub friend_impl: bool,
3233d722a9Sopenharmony_ci    pub is_complete: bool,
3333d722a9Sopenharmony_ci    pub destroy: bool,
3433d722a9Sopenharmony_ci    pub deleter_if: bool,
3533d722a9Sopenharmony_ci    pub content: Content<'a>,
3633d722a9Sopenharmony_ci}
3733d722a9Sopenharmony_ci
3833d722a9Sopenharmony_ciimpl<'a> Builtins<'a> {
3933d722a9Sopenharmony_ci    pub fn new() -> Self {
4033d722a9Sopenharmony_ci        Builtins::default()
4133d722a9Sopenharmony_ci    }
4233d722a9Sopenharmony_ci}
4333d722a9Sopenharmony_ci
4433d722a9Sopenharmony_cipub(super) fn write(out: &mut OutFile) {
4533d722a9Sopenharmony_ci    if out.builtin == Default::default() {
4633d722a9Sopenharmony_ci        return;
4733d722a9Sopenharmony_ci    }
4833d722a9Sopenharmony_ci
4933d722a9Sopenharmony_ci    let include = &mut out.include;
5033d722a9Sopenharmony_ci    let builtin = &mut out.builtin;
5133d722a9Sopenharmony_ci    let out = &mut builtin.content;
5233d722a9Sopenharmony_ci
5333d722a9Sopenharmony_ci    if builtin.rust_string {
5433d722a9Sopenharmony_ci        include.array = true;
5533d722a9Sopenharmony_ci        include.cstdint = true;
5633d722a9Sopenharmony_ci        include.string = true;
5733d722a9Sopenharmony_ci    }
5833d722a9Sopenharmony_ci
5933d722a9Sopenharmony_ci    if builtin.rust_str {
6033d722a9Sopenharmony_ci        include.array = true;
6133d722a9Sopenharmony_ci        include.cstdint = true;
6233d722a9Sopenharmony_ci        include.string = true;
6333d722a9Sopenharmony_ci        builtin.friend_impl = true;
6433d722a9Sopenharmony_ci    }
6533d722a9Sopenharmony_ci
6633d722a9Sopenharmony_ci    if builtin.rust_vec {
6733d722a9Sopenharmony_ci        include.algorithm = true;
6833d722a9Sopenharmony_ci        include.array = true;
6933d722a9Sopenharmony_ci        include.cassert = true;
7033d722a9Sopenharmony_ci        include.cstddef = true;
7133d722a9Sopenharmony_ci        include.cstdint = true;
7233d722a9Sopenharmony_ci        include.initializer_list = true;
7333d722a9Sopenharmony_ci        include.iterator = true;
7433d722a9Sopenharmony_ci        include.new = true;
7533d722a9Sopenharmony_ci        include.stdexcept = true;
7633d722a9Sopenharmony_ci        include.type_traits = true;
7733d722a9Sopenharmony_ci        include.utility = true;
7833d722a9Sopenharmony_ci        builtin.panic = true;
7933d722a9Sopenharmony_ci        builtin.rust_slice = true;
8033d722a9Sopenharmony_ci        builtin.unsafe_bitcopy_t = true;
8133d722a9Sopenharmony_ci    }
8233d722a9Sopenharmony_ci
8333d722a9Sopenharmony_ci    if builtin.rust_slice {
8433d722a9Sopenharmony_ci        include.array = true;
8533d722a9Sopenharmony_ci        include.cassert = true;
8633d722a9Sopenharmony_ci        include.cstddef = true;
8733d722a9Sopenharmony_ci        include.cstdint = true;
8833d722a9Sopenharmony_ci        include.iterator = true;
8933d722a9Sopenharmony_ci        include.stdexcept = true;
9033d722a9Sopenharmony_ci        include.type_traits = true;
9133d722a9Sopenharmony_ci        builtin.friend_impl = true;
9233d722a9Sopenharmony_ci        builtin.layout = true;
9333d722a9Sopenharmony_ci        builtin.panic = true;
9433d722a9Sopenharmony_ci    }
9533d722a9Sopenharmony_ci
9633d722a9Sopenharmony_ci    if builtin.rust_box {
9733d722a9Sopenharmony_ci        include.new = true;
9833d722a9Sopenharmony_ci        include.type_traits = true;
9933d722a9Sopenharmony_ci        include.utility = true;
10033d722a9Sopenharmony_ci    }
10133d722a9Sopenharmony_ci
10233d722a9Sopenharmony_ci    if builtin.rust_fn {
10333d722a9Sopenharmony_ci        include.utility = true;
10433d722a9Sopenharmony_ci    }
10533d722a9Sopenharmony_ci
10633d722a9Sopenharmony_ci    if builtin.rust_error {
10733d722a9Sopenharmony_ci        include.exception = true;
10833d722a9Sopenharmony_ci        builtin.friend_impl = true;
10933d722a9Sopenharmony_ci    }
11033d722a9Sopenharmony_ci
11133d722a9Sopenharmony_ci    if builtin.rust_isize {
11233d722a9Sopenharmony_ci        include.basetsd = true;
11333d722a9Sopenharmony_ci        include.sys_types = true;
11433d722a9Sopenharmony_ci    }
11533d722a9Sopenharmony_ci
11633d722a9Sopenharmony_ci    if builtin.relocatable_or_array {
11733d722a9Sopenharmony_ci        include.cstddef = true;
11833d722a9Sopenharmony_ci        builtin.relocatable = true;
11933d722a9Sopenharmony_ci    }
12033d722a9Sopenharmony_ci
12133d722a9Sopenharmony_ci    if builtin.relocatable {
12233d722a9Sopenharmony_ci        include.type_traits = true;
12333d722a9Sopenharmony_ci    }
12433d722a9Sopenharmony_ci
12533d722a9Sopenharmony_ci    if builtin.layout {
12633d722a9Sopenharmony_ci        include.type_traits = true;
12733d722a9Sopenharmony_ci        include.cstddef = true;
12833d722a9Sopenharmony_ci        builtin.is_complete = true;
12933d722a9Sopenharmony_ci    }
13033d722a9Sopenharmony_ci
13133d722a9Sopenharmony_ci    if builtin.is_complete {
13233d722a9Sopenharmony_ci        include.cstddef = true;
13333d722a9Sopenharmony_ci        include.type_traits = true;
13433d722a9Sopenharmony_ci    }
13533d722a9Sopenharmony_ci
13633d722a9Sopenharmony_ci    if builtin.unsafe_bitcopy {
13733d722a9Sopenharmony_ci        builtin.unsafe_bitcopy_t = true;
13833d722a9Sopenharmony_ci    }
13933d722a9Sopenharmony_ci
14033d722a9Sopenharmony_ci    if builtin.trycatch {
14133d722a9Sopenharmony_ci        builtin.ptr_len = true;
14233d722a9Sopenharmony_ci    }
14333d722a9Sopenharmony_ci
14433d722a9Sopenharmony_ci    out.begin_block(Block::Namespace("rust"));
14533d722a9Sopenharmony_ci    out.begin_block(Block::InlineNamespace("cxxbridge1"));
14633d722a9Sopenharmony_ci
14733d722a9Sopenharmony_ci    let cxx_header = include.has_cxx_header();
14833d722a9Sopenharmony_ci    if !cxx_header {
14933d722a9Sopenharmony_ci        writeln!(out, "// #include \"rust/cxx.h\"");
15033d722a9Sopenharmony_ci
15133d722a9Sopenharmony_ci        ifndef::write(out, builtin.panic, "CXXBRIDGE1_PANIC");
15233d722a9Sopenharmony_ci
15333d722a9Sopenharmony_ci        if builtin.rust_string {
15433d722a9Sopenharmony_ci            out.next_section();
15533d722a9Sopenharmony_ci            writeln!(out, "struct unsafe_bitcopy_t;");
15633d722a9Sopenharmony_ci        }
15733d722a9Sopenharmony_ci
15833d722a9Sopenharmony_ci        if builtin.friend_impl {
15933d722a9Sopenharmony_ci            out.begin_block(Block::AnonymousNamespace);
16033d722a9Sopenharmony_ci            writeln!(out, "template <typename T>");
16133d722a9Sopenharmony_ci            writeln!(out, "class impl;");
16233d722a9Sopenharmony_ci            out.end_block(Block::AnonymousNamespace);
16333d722a9Sopenharmony_ci        }
16433d722a9Sopenharmony_ci
16533d722a9Sopenharmony_ci        out.next_section();
16633d722a9Sopenharmony_ci        if builtin.rust_str && !builtin.rust_string {
16733d722a9Sopenharmony_ci            writeln!(out, "class String;");
16833d722a9Sopenharmony_ci        }
16933d722a9Sopenharmony_ci        if builtin.layout && !builtin.opaque {
17033d722a9Sopenharmony_ci            writeln!(out, "class Opaque;");
17133d722a9Sopenharmony_ci        }
17233d722a9Sopenharmony_ci
17333d722a9Sopenharmony_ci        if builtin.rust_slice {
17433d722a9Sopenharmony_ci            out.next_section();
17533d722a9Sopenharmony_ci            writeln!(out, "template <typename T>");
17633d722a9Sopenharmony_ci            writeln!(out, "::std::size_t size_of();");
17733d722a9Sopenharmony_ci            writeln!(out, "template <typename T>");
17833d722a9Sopenharmony_ci            writeln!(out, "::std::size_t align_of();");
17933d722a9Sopenharmony_ci        }
18033d722a9Sopenharmony_ci
18133d722a9Sopenharmony_ci        ifndef::write(out, builtin.rust_string, "CXXBRIDGE1_RUST_STRING");
18233d722a9Sopenharmony_ci        ifndef::write(out, builtin.rust_str, "CXXBRIDGE1_RUST_STR");
18333d722a9Sopenharmony_ci        ifndef::write(out, builtin.rust_slice, "CXXBRIDGE1_RUST_SLICE");
18433d722a9Sopenharmony_ci        ifndef::write(out, builtin.rust_box, "CXXBRIDGE1_RUST_BOX");
18533d722a9Sopenharmony_ci        ifndef::write(out, builtin.unsafe_bitcopy_t, "CXXBRIDGE1_RUST_BITCOPY_T");
18633d722a9Sopenharmony_ci        ifndef::write(out, builtin.unsafe_bitcopy, "CXXBRIDGE1_RUST_BITCOPY");
18733d722a9Sopenharmony_ci        ifndef::write(out, builtin.rust_vec, "CXXBRIDGE1_RUST_VEC");
18833d722a9Sopenharmony_ci        ifndef::write(out, builtin.rust_fn, "CXXBRIDGE1_RUST_FN");
18933d722a9Sopenharmony_ci        ifndef::write(out, builtin.rust_error, "CXXBRIDGE1_RUST_ERROR");
19033d722a9Sopenharmony_ci        ifndef::write(out, builtin.rust_isize, "CXXBRIDGE1_RUST_ISIZE");
19133d722a9Sopenharmony_ci        ifndef::write(out, builtin.opaque, "CXXBRIDGE1_RUST_OPAQUE");
19233d722a9Sopenharmony_ci        ifndef::write(out, builtin.is_complete, "CXXBRIDGE1_IS_COMPLETE");
19333d722a9Sopenharmony_ci        ifndef::write(out, builtin.layout, "CXXBRIDGE1_LAYOUT");
19433d722a9Sopenharmony_ci        ifndef::write(out, builtin.relocatable, "CXXBRIDGE1_RELOCATABLE");
19533d722a9Sopenharmony_ci    }
19633d722a9Sopenharmony_ci
19733d722a9Sopenharmony_ci    if builtin.rust_str_new_unchecked {
19833d722a9Sopenharmony_ci        out.next_section();
19933d722a9Sopenharmony_ci        writeln!(out, "class Str::uninit {{}};");
20033d722a9Sopenharmony_ci        writeln!(out, "inline Str::Str(uninit) noexcept {{}}");
20133d722a9Sopenharmony_ci    }
20233d722a9Sopenharmony_ci
20333d722a9Sopenharmony_ci    if builtin.rust_slice_new {
20433d722a9Sopenharmony_ci        out.next_section();
20533d722a9Sopenharmony_ci        writeln!(out, "template <typename T>");
20633d722a9Sopenharmony_ci        writeln!(out, "class Slice<T>::uninit {{}};");
20733d722a9Sopenharmony_ci        writeln!(out, "template <typename T>");
20833d722a9Sopenharmony_ci        writeln!(out, "inline Slice<T>::Slice(uninit) noexcept {{}}");
20933d722a9Sopenharmony_ci    }
21033d722a9Sopenharmony_ci
21133d722a9Sopenharmony_ci    out.begin_block(Block::Namespace("repr"));
21233d722a9Sopenharmony_ci
21333d722a9Sopenharmony_ci    if builtin.repr_fat {
21433d722a9Sopenharmony_ci        include.array = true;
21533d722a9Sopenharmony_ci        include.cstdint = true;
21633d722a9Sopenharmony_ci        out.next_section();
21733d722a9Sopenharmony_ci        writeln!(out, "using Fat = ::std::array<::std::uintptr_t, 2>;");
21833d722a9Sopenharmony_ci    }
21933d722a9Sopenharmony_ci
22033d722a9Sopenharmony_ci    if builtin.ptr_len {
22133d722a9Sopenharmony_ci        include.cstddef = true;
22233d722a9Sopenharmony_ci        out.next_section();
22333d722a9Sopenharmony_ci        writeln!(out, "struct PtrLen final {{");
22433d722a9Sopenharmony_ci        writeln!(out, "  void *ptr;");
22533d722a9Sopenharmony_ci        writeln!(out, "  ::std::size_t len;");
22633d722a9Sopenharmony_ci        writeln!(out, "}};");
22733d722a9Sopenharmony_ci    }
22833d722a9Sopenharmony_ci
22933d722a9Sopenharmony_ci    out.end_block(Block::Namespace("repr"));
23033d722a9Sopenharmony_ci
23133d722a9Sopenharmony_ci    out.begin_block(Block::Namespace("detail"));
23233d722a9Sopenharmony_ci
23333d722a9Sopenharmony_ci    if builtin.maybe_uninit {
23433d722a9Sopenharmony_ci        include.cstddef = true;
23533d722a9Sopenharmony_ci        include.new = true;
23633d722a9Sopenharmony_ci        out.next_section();
23733d722a9Sopenharmony_ci        writeln!(out, "template <typename T, typename = void *>");
23833d722a9Sopenharmony_ci        writeln!(out, "struct operator_new {{");
23933d722a9Sopenharmony_ci        writeln!(
24033d722a9Sopenharmony_ci            out,
24133d722a9Sopenharmony_ci            "  void *operator()(::std::size_t sz) {{ return ::operator new(sz); }}",
24233d722a9Sopenharmony_ci        );
24333d722a9Sopenharmony_ci        writeln!(out, "}};");
24433d722a9Sopenharmony_ci        out.next_section();
24533d722a9Sopenharmony_ci        writeln!(out, "template <typename T>");
24633d722a9Sopenharmony_ci        writeln!(
24733d722a9Sopenharmony_ci            out,
24833d722a9Sopenharmony_ci            "struct operator_new<T, decltype(T::operator new(sizeof(T)))> {{",
24933d722a9Sopenharmony_ci        );
25033d722a9Sopenharmony_ci        writeln!(
25133d722a9Sopenharmony_ci            out,
25233d722a9Sopenharmony_ci            "  void *operator()(::std::size_t sz) {{ return T::operator new(sz); }}",
25333d722a9Sopenharmony_ci        );
25433d722a9Sopenharmony_ci        writeln!(out, "}};");
25533d722a9Sopenharmony_ci    }
25633d722a9Sopenharmony_ci
25733d722a9Sopenharmony_ci    if builtin.trycatch {
25833d722a9Sopenharmony_ci        include.string = true;
25933d722a9Sopenharmony_ci        out.next_section();
26033d722a9Sopenharmony_ci        writeln!(out, "class Fail final {{");
26133d722a9Sopenharmony_ci        writeln!(out, "  ::rust::repr::PtrLen &throw$;");
26233d722a9Sopenharmony_ci        writeln!(out, "public:");
26333d722a9Sopenharmony_ci        writeln!(
26433d722a9Sopenharmony_ci            out,
26533d722a9Sopenharmony_ci            "  Fail(::rust::repr::PtrLen &throw$) noexcept : throw$(throw$) {{}}",
26633d722a9Sopenharmony_ci        );
26733d722a9Sopenharmony_ci        writeln!(out, "  void operator()(char const *) noexcept;");
26833d722a9Sopenharmony_ci        writeln!(out, "  void operator()(std::string const &) noexcept;");
26933d722a9Sopenharmony_ci        writeln!(out, "}};");
27033d722a9Sopenharmony_ci    }
27133d722a9Sopenharmony_ci
27233d722a9Sopenharmony_ci    out.end_block(Block::Namespace("detail"));
27333d722a9Sopenharmony_ci
27433d722a9Sopenharmony_ci    if builtin.manually_drop {
27533d722a9Sopenharmony_ci        out.next_section();
27633d722a9Sopenharmony_ci        include.utility = true;
27733d722a9Sopenharmony_ci        writeln!(out, "template <typename T>");
27833d722a9Sopenharmony_ci        writeln!(out, "union ManuallyDrop {{");
27933d722a9Sopenharmony_ci        writeln!(out, "  T value;");
28033d722a9Sopenharmony_ci        writeln!(
28133d722a9Sopenharmony_ci            out,
28233d722a9Sopenharmony_ci            "  ManuallyDrop(T &&value) : value(::std::move(value)) {{}}",
28333d722a9Sopenharmony_ci        );
28433d722a9Sopenharmony_ci        writeln!(out, "  ~ManuallyDrop() {{}}");
28533d722a9Sopenharmony_ci        writeln!(out, "}};");
28633d722a9Sopenharmony_ci    }
28733d722a9Sopenharmony_ci
28833d722a9Sopenharmony_ci    if builtin.maybe_uninit {
28933d722a9Sopenharmony_ci        include.cstddef = true;
29033d722a9Sopenharmony_ci        out.next_section();
29133d722a9Sopenharmony_ci        writeln!(out, "template <typename T>");
29233d722a9Sopenharmony_ci        writeln!(out, "union MaybeUninit {{");
29333d722a9Sopenharmony_ci        writeln!(out, "  T value;");
29433d722a9Sopenharmony_ci        writeln!(
29533d722a9Sopenharmony_ci            out,
29633d722a9Sopenharmony_ci            "  void *operator new(::std::size_t sz) {{ return detail::operator_new<T>{{}}(sz); }}",
29733d722a9Sopenharmony_ci        );
29833d722a9Sopenharmony_ci        writeln!(out, "  MaybeUninit() {{}}");
29933d722a9Sopenharmony_ci        writeln!(out, "  ~MaybeUninit() {{}}");
30033d722a9Sopenharmony_ci        writeln!(out, "}};");
30133d722a9Sopenharmony_ci    }
30233d722a9Sopenharmony_ci
30333d722a9Sopenharmony_ci    out.begin_block(Block::AnonymousNamespace);
30433d722a9Sopenharmony_ci
30533d722a9Sopenharmony_ci    if builtin.rust_str_new_unchecked || builtin.rust_str_repr {
30633d722a9Sopenharmony_ci        out.next_section();
30733d722a9Sopenharmony_ci        writeln!(out, "template <>");
30833d722a9Sopenharmony_ci        writeln!(out, "class impl<Str> final {{");
30933d722a9Sopenharmony_ci        writeln!(out, "public:");
31033d722a9Sopenharmony_ci        if builtin.rust_str_new_unchecked {
31133d722a9Sopenharmony_ci            writeln!(
31233d722a9Sopenharmony_ci                out,
31333d722a9Sopenharmony_ci                "  static Str new_unchecked(repr::Fat repr) noexcept {{",
31433d722a9Sopenharmony_ci            );
31533d722a9Sopenharmony_ci            writeln!(out, "    Str str = Str::uninit{{}};");
31633d722a9Sopenharmony_ci            writeln!(out, "    str.repr = repr;");
31733d722a9Sopenharmony_ci            writeln!(out, "    return str;");
31833d722a9Sopenharmony_ci            writeln!(out, "  }}");
31933d722a9Sopenharmony_ci        }
32033d722a9Sopenharmony_ci        if builtin.rust_str_repr {
32133d722a9Sopenharmony_ci            writeln!(out, "  static repr::Fat repr(Str str) noexcept {{");
32233d722a9Sopenharmony_ci            writeln!(out, "    return str.repr;");
32333d722a9Sopenharmony_ci            writeln!(out, "  }}");
32433d722a9Sopenharmony_ci        }
32533d722a9Sopenharmony_ci        writeln!(out, "}};");
32633d722a9Sopenharmony_ci    }
32733d722a9Sopenharmony_ci
32833d722a9Sopenharmony_ci    if builtin.rust_slice_new || builtin.rust_slice_repr {
32933d722a9Sopenharmony_ci        out.next_section();
33033d722a9Sopenharmony_ci        writeln!(out, "template <typename T>");
33133d722a9Sopenharmony_ci        writeln!(out, "class impl<Slice<T>> final {{");
33233d722a9Sopenharmony_ci        writeln!(out, "public:");
33333d722a9Sopenharmony_ci        if builtin.rust_slice_new {
33433d722a9Sopenharmony_ci            writeln!(out, "  static Slice<T> slice(repr::Fat repr) noexcept {{");
33533d722a9Sopenharmony_ci            writeln!(out, "    Slice<T> slice = typename Slice<T>::uninit{{}};");
33633d722a9Sopenharmony_ci            writeln!(out, "    slice.repr = repr;");
33733d722a9Sopenharmony_ci            writeln!(out, "    return slice;");
33833d722a9Sopenharmony_ci            writeln!(out, "  }}");
33933d722a9Sopenharmony_ci        }
34033d722a9Sopenharmony_ci        if builtin.rust_slice_repr {
34133d722a9Sopenharmony_ci            writeln!(out, "  static repr::Fat repr(Slice<T> slice) noexcept {{");
34233d722a9Sopenharmony_ci            writeln!(out, "    return slice.repr;");
34333d722a9Sopenharmony_ci            writeln!(out, "  }}");
34433d722a9Sopenharmony_ci        }
34533d722a9Sopenharmony_ci        writeln!(out, "}};");
34633d722a9Sopenharmony_ci    }
34733d722a9Sopenharmony_ci
34833d722a9Sopenharmony_ci    if builtin.rust_error {
34933d722a9Sopenharmony_ci        out.next_section();
35033d722a9Sopenharmony_ci        writeln!(out, "template <>");
35133d722a9Sopenharmony_ci        writeln!(out, "class impl<Error> final {{");
35233d722a9Sopenharmony_ci        writeln!(out, "public:");
35333d722a9Sopenharmony_ci        writeln!(out, "  static Error error(repr::PtrLen repr) noexcept {{");
35433d722a9Sopenharmony_ci        writeln!(out, "    Error error;");
35533d722a9Sopenharmony_ci        writeln!(out, "    error.msg = static_cast<char const *>(repr.ptr);");
35633d722a9Sopenharmony_ci        writeln!(out, "    error.len = repr.len;");
35733d722a9Sopenharmony_ci        writeln!(out, "    return error;");
35833d722a9Sopenharmony_ci        writeln!(out, "  }}");
35933d722a9Sopenharmony_ci        writeln!(out, "}};");
36033d722a9Sopenharmony_ci    }
36133d722a9Sopenharmony_ci
36233d722a9Sopenharmony_ci    if builtin.destroy {
36333d722a9Sopenharmony_ci        out.next_section();
36433d722a9Sopenharmony_ci        writeln!(out, "template <typename T>");
36533d722a9Sopenharmony_ci        writeln!(out, "void destroy(T *ptr) {{");
36633d722a9Sopenharmony_ci        writeln!(out, "  ptr->~T();");
36733d722a9Sopenharmony_ci        writeln!(out, "}}");
36833d722a9Sopenharmony_ci    }
36933d722a9Sopenharmony_ci
37033d722a9Sopenharmony_ci    if builtin.deleter_if {
37133d722a9Sopenharmony_ci        out.next_section();
37233d722a9Sopenharmony_ci        writeln!(out, "template <bool> struct deleter_if {{");
37333d722a9Sopenharmony_ci        writeln!(out, "  template <typename T> void operator()(T *) {{}}");
37433d722a9Sopenharmony_ci        writeln!(out, "}};");
37533d722a9Sopenharmony_ci        out.next_section();
37633d722a9Sopenharmony_ci        writeln!(out, "template <> struct deleter_if<true> {{");
37733d722a9Sopenharmony_ci        writeln!(
37833d722a9Sopenharmony_ci            out,
37933d722a9Sopenharmony_ci            "  template <typename T> void operator()(T *ptr) {{ ptr->~T(); }}",
38033d722a9Sopenharmony_ci        );
38133d722a9Sopenharmony_ci        writeln!(out, "}};");
38233d722a9Sopenharmony_ci    }
38333d722a9Sopenharmony_ci
38433d722a9Sopenharmony_ci    if builtin.relocatable_or_array {
38533d722a9Sopenharmony_ci        out.next_section();
38633d722a9Sopenharmony_ci        writeln!(out, "template <typename T>");
38733d722a9Sopenharmony_ci        writeln!(out, "struct IsRelocatableOrArray : IsRelocatable<T> {{}};");
38833d722a9Sopenharmony_ci        writeln!(out, "template <typename T, ::std::size_t N>");
38933d722a9Sopenharmony_ci        writeln!(
39033d722a9Sopenharmony_ci            out,
39133d722a9Sopenharmony_ci            "struct IsRelocatableOrArray<T[N]> : IsRelocatableOrArray<T> {{}};",
39233d722a9Sopenharmony_ci        );
39333d722a9Sopenharmony_ci    }
39433d722a9Sopenharmony_ci
39533d722a9Sopenharmony_ci    out.end_block(Block::AnonymousNamespace);
39633d722a9Sopenharmony_ci    out.end_block(Block::InlineNamespace("cxxbridge1"));
39733d722a9Sopenharmony_ci
39833d722a9Sopenharmony_ci    if builtin.trycatch {
39933d722a9Sopenharmony_ci        out.begin_block(Block::Namespace("behavior"));
40033d722a9Sopenharmony_ci        include.exception = true;
40133d722a9Sopenharmony_ci        include.type_traits = true;
40233d722a9Sopenharmony_ci        include.utility = true;
40333d722a9Sopenharmony_ci        writeln!(out, "class missing {{}};");
40433d722a9Sopenharmony_ci        writeln!(out, "missing trycatch(...);");
40533d722a9Sopenharmony_ci        writeln!(out);
40633d722a9Sopenharmony_ci        writeln!(out, "template <typename Try, typename Fail>");
40733d722a9Sopenharmony_ci        writeln!(out, "static typename ::std::enable_if<");
40833d722a9Sopenharmony_ci        writeln!(
40933d722a9Sopenharmony_ci            out,
41033d722a9Sopenharmony_ci            "    ::std::is_same<decltype(trycatch(::std::declval<Try>(), ::std::declval<Fail>())),",
41133d722a9Sopenharmony_ci        );
41233d722a9Sopenharmony_ci        writeln!(out, "                 missing>::value>::type");
41333d722a9Sopenharmony_ci        writeln!(out, "trycatch(Try &&func, Fail &&fail) noexcept try {{");
41433d722a9Sopenharmony_ci        writeln!(out, "  func();");
41533d722a9Sopenharmony_ci        writeln!(out, "}} catch (::std::exception const &e) {{");
41633d722a9Sopenharmony_ci        writeln!(out, "  fail(e.what());");
41733d722a9Sopenharmony_ci        writeln!(out, "}}");
41833d722a9Sopenharmony_ci        out.end_block(Block::Namespace("behavior"));
41933d722a9Sopenharmony_ci    }
42033d722a9Sopenharmony_ci
42133d722a9Sopenharmony_ci    out.end_block(Block::Namespace("rust"));
42233d722a9Sopenharmony_ci}
423