133d722a9Sopenharmony_ciuse crate::gen::out::{Content, OutFile}; 233d722a9Sopenharmony_ciuse crate::syntax::{self, IncludeKind}; 333d722a9Sopenharmony_ciuse std::ops::{Deref, DerefMut}; 433d722a9Sopenharmony_ci 533d722a9Sopenharmony_ci/// The complete contents of the "rust/cxx.h" header. 633d722a9Sopenharmony_cipub static HEADER: &str = include_str!("include/cxx.h"); 733d722a9Sopenharmony_ci 833d722a9Sopenharmony_ci/// A header to #include. 933d722a9Sopenharmony_ci/// 1033d722a9Sopenharmony_ci/// The cxxbridge tool does not parse or even require the given paths to exist; 1133d722a9Sopenharmony_ci/// they simply go into the generated C++ code as #include lines. 1233d722a9Sopenharmony_ci#[derive(Clone, PartialEq, Debug)] 1333d722a9Sopenharmony_cipub struct Include { 1433d722a9Sopenharmony_ci /// The header's path, not including the enclosing quotation marks or angle 1533d722a9Sopenharmony_ci /// brackets. 1633d722a9Sopenharmony_ci pub path: String, 1733d722a9Sopenharmony_ci /// Whether to emit `#include "path"` or `#include <path>`. 1833d722a9Sopenharmony_ci pub kind: IncludeKind, 1933d722a9Sopenharmony_ci} 2033d722a9Sopenharmony_ci 2133d722a9Sopenharmony_ci#[derive(Default, PartialEq)] 2233d722a9Sopenharmony_cipub struct Includes<'a> { 2333d722a9Sopenharmony_ci pub custom: Vec<Include>, 2433d722a9Sopenharmony_ci pub algorithm: bool, 2533d722a9Sopenharmony_ci pub array: bool, 2633d722a9Sopenharmony_ci pub cassert: bool, 2733d722a9Sopenharmony_ci pub cstddef: bool, 2833d722a9Sopenharmony_ci pub cstdint: bool, 2933d722a9Sopenharmony_ci pub cstring: bool, 3033d722a9Sopenharmony_ci pub exception: bool, 3133d722a9Sopenharmony_ci pub functional: bool, 3233d722a9Sopenharmony_ci pub initializer_list: bool, 3333d722a9Sopenharmony_ci pub iterator: bool, 3433d722a9Sopenharmony_ci pub memory: bool, 3533d722a9Sopenharmony_ci pub new: bool, 3633d722a9Sopenharmony_ci pub stdexcept: bool, 3733d722a9Sopenharmony_ci pub string: bool, 3833d722a9Sopenharmony_ci pub type_traits: bool, 3933d722a9Sopenharmony_ci pub utility: bool, 4033d722a9Sopenharmony_ci pub vector: bool, 4133d722a9Sopenharmony_ci pub basetsd: bool, 4233d722a9Sopenharmony_ci pub sys_types: bool, 4333d722a9Sopenharmony_ci pub content: Content<'a>, 4433d722a9Sopenharmony_ci} 4533d722a9Sopenharmony_ci 4633d722a9Sopenharmony_ciimpl<'a> Includes<'a> { 4733d722a9Sopenharmony_ci pub fn new() -> Self { 4833d722a9Sopenharmony_ci Includes::default() 4933d722a9Sopenharmony_ci } 5033d722a9Sopenharmony_ci 5133d722a9Sopenharmony_ci pub fn insert(&mut self, include: impl Into<Include>) { 5233d722a9Sopenharmony_ci self.custom.push(include.into()); 5333d722a9Sopenharmony_ci } 5433d722a9Sopenharmony_ci 5533d722a9Sopenharmony_ci pub fn has_cxx_header(&self) -> bool { 5633d722a9Sopenharmony_ci self.custom 5733d722a9Sopenharmony_ci .iter() 5833d722a9Sopenharmony_ci .any(|header| header.path == "rust/cxx.h" || header.path == "rust\\cxx.h") 5933d722a9Sopenharmony_ci } 6033d722a9Sopenharmony_ci} 6133d722a9Sopenharmony_ci 6233d722a9Sopenharmony_cipub(super) fn write(out: &mut OutFile) { 6333d722a9Sopenharmony_ci let header = out.header; 6433d722a9Sopenharmony_ci let include = &mut out.include; 6533d722a9Sopenharmony_ci let cxx_header = include.has_cxx_header(); 6633d722a9Sopenharmony_ci let out = &mut include.content; 6733d722a9Sopenharmony_ci 6833d722a9Sopenharmony_ci if header { 6933d722a9Sopenharmony_ci writeln!(out, "#pragma once"); 7033d722a9Sopenharmony_ci } 7133d722a9Sopenharmony_ci 7233d722a9Sopenharmony_ci for include in &include.custom { 7333d722a9Sopenharmony_ci match include.kind { 7433d722a9Sopenharmony_ci IncludeKind::Quoted => { 7533d722a9Sopenharmony_ci writeln!(out, "#include \"{}\"", include.path.escape_default()); 7633d722a9Sopenharmony_ci } 7733d722a9Sopenharmony_ci IncludeKind::Bracketed => { 7833d722a9Sopenharmony_ci writeln!(out, "#include <{}>", include.path); 7933d722a9Sopenharmony_ci } 8033d722a9Sopenharmony_ci } 8133d722a9Sopenharmony_ci } 8233d722a9Sopenharmony_ci 8333d722a9Sopenharmony_ci let Includes { 8433d722a9Sopenharmony_ci custom: _, 8533d722a9Sopenharmony_ci algorithm, 8633d722a9Sopenharmony_ci array, 8733d722a9Sopenharmony_ci cassert, 8833d722a9Sopenharmony_ci cstddef, 8933d722a9Sopenharmony_ci cstdint, 9033d722a9Sopenharmony_ci cstring, 9133d722a9Sopenharmony_ci exception, 9233d722a9Sopenharmony_ci functional, 9333d722a9Sopenharmony_ci initializer_list, 9433d722a9Sopenharmony_ci iterator, 9533d722a9Sopenharmony_ci memory, 9633d722a9Sopenharmony_ci new, 9733d722a9Sopenharmony_ci stdexcept, 9833d722a9Sopenharmony_ci string, 9933d722a9Sopenharmony_ci type_traits, 10033d722a9Sopenharmony_ci utility, 10133d722a9Sopenharmony_ci vector, 10233d722a9Sopenharmony_ci basetsd, 10333d722a9Sopenharmony_ci sys_types, 10433d722a9Sopenharmony_ci content: _, 10533d722a9Sopenharmony_ci } = *include; 10633d722a9Sopenharmony_ci 10733d722a9Sopenharmony_ci if algorithm && !cxx_header { 10833d722a9Sopenharmony_ci writeln!(out, "#include <algorithm>"); 10933d722a9Sopenharmony_ci } 11033d722a9Sopenharmony_ci if array && !cxx_header { 11133d722a9Sopenharmony_ci writeln!(out, "#include <array>"); 11233d722a9Sopenharmony_ci } 11333d722a9Sopenharmony_ci if cassert && !cxx_header { 11433d722a9Sopenharmony_ci writeln!(out, "#include <cassert>"); 11533d722a9Sopenharmony_ci } 11633d722a9Sopenharmony_ci if cstddef && !cxx_header { 11733d722a9Sopenharmony_ci writeln!(out, "#include <cstddef>"); 11833d722a9Sopenharmony_ci } 11933d722a9Sopenharmony_ci if cstdint && !cxx_header { 12033d722a9Sopenharmony_ci writeln!(out, "#include <cstdint>"); 12133d722a9Sopenharmony_ci } 12233d722a9Sopenharmony_ci if cstring { 12333d722a9Sopenharmony_ci writeln!(out, "#include <cstring>"); 12433d722a9Sopenharmony_ci } 12533d722a9Sopenharmony_ci if exception && !cxx_header { 12633d722a9Sopenharmony_ci writeln!(out, "#include <exception>"); 12733d722a9Sopenharmony_ci } 12833d722a9Sopenharmony_ci if functional { 12933d722a9Sopenharmony_ci writeln!(out, "#include <functional>"); 13033d722a9Sopenharmony_ci } 13133d722a9Sopenharmony_ci if initializer_list && !cxx_header { 13233d722a9Sopenharmony_ci writeln!(out, "#include <initializer_list>"); 13333d722a9Sopenharmony_ci } 13433d722a9Sopenharmony_ci if iterator && !cxx_header { 13533d722a9Sopenharmony_ci writeln!(out, "#include <iterator>"); 13633d722a9Sopenharmony_ci } 13733d722a9Sopenharmony_ci if memory { 13833d722a9Sopenharmony_ci writeln!(out, "#include <memory>"); 13933d722a9Sopenharmony_ci } 14033d722a9Sopenharmony_ci if new && !cxx_header { 14133d722a9Sopenharmony_ci writeln!(out, "#include <new>"); 14233d722a9Sopenharmony_ci } 14333d722a9Sopenharmony_ci if stdexcept && !cxx_header { 14433d722a9Sopenharmony_ci writeln!(out, "#include <stdexcept>"); 14533d722a9Sopenharmony_ci } 14633d722a9Sopenharmony_ci if string && !cxx_header { 14733d722a9Sopenharmony_ci writeln!(out, "#include <string>"); 14833d722a9Sopenharmony_ci } 14933d722a9Sopenharmony_ci if type_traits && !cxx_header { 15033d722a9Sopenharmony_ci writeln!(out, "#include <type_traits>"); 15133d722a9Sopenharmony_ci } 15233d722a9Sopenharmony_ci if utility && !cxx_header { 15333d722a9Sopenharmony_ci writeln!(out, "#include <utility>"); 15433d722a9Sopenharmony_ci } 15533d722a9Sopenharmony_ci if vector && !cxx_header { 15633d722a9Sopenharmony_ci writeln!(out, "#include <vector>"); 15733d722a9Sopenharmony_ci } 15833d722a9Sopenharmony_ci if basetsd && !cxx_header { 15933d722a9Sopenharmony_ci writeln!(out, "#if defined(_WIN32)"); 16033d722a9Sopenharmony_ci writeln!(out, "#include <basetsd.h>"); 16133d722a9Sopenharmony_ci } 16233d722a9Sopenharmony_ci if sys_types && !cxx_header { 16333d722a9Sopenharmony_ci if basetsd { 16433d722a9Sopenharmony_ci writeln!(out, "#else"); 16533d722a9Sopenharmony_ci } else { 16633d722a9Sopenharmony_ci writeln!(out, "#if not defined(_WIN32)"); 16733d722a9Sopenharmony_ci } 16833d722a9Sopenharmony_ci } 16933d722a9Sopenharmony_ci if sys_types && !cxx_header { 17033d722a9Sopenharmony_ci writeln!(out, "#include <sys/types.h>"); 17133d722a9Sopenharmony_ci } 17233d722a9Sopenharmony_ci if (basetsd || sys_types) && !cxx_header { 17333d722a9Sopenharmony_ci writeln!(out, "#endif"); 17433d722a9Sopenharmony_ci } 17533d722a9Sopenharmony_ci} 17633d722a9Sopenharmony_ci 17733d722a9Sopenharmony_ciimpl<'i, 'a> Extend<&'i Include> for Includes<'a> { 17833d722a9Sopenharmony_ci fn extend<I: IntoIterator<Item = &'i Include>>(&mut self, iter: I) { 17933d722a9Sopenharmony_ci self.custom.extend(iter.into_iter().cloned()); 18033d722a9Sopenharmony_ci } 18133d722a9Sopenharmony_ci} 18233d722a9Sopenharmony_ci 18333d722a9Sopenharmony_ciimpl<'i> From<&'i syntax::Include> for Include { 18433d722a9Sopenharmony_ci fn from(include: &syntax::Include) -> Self { 18533d722a9Sopenharmony_ci Include { 18633d722a9Sopenharmony_ci path: include.path.clone(), 18733d722a9Sopenharmony_ci kind: include.kind, 18833d722a9Sopenharmony_ci } 18933d722a9Sopenharmony_ci } 19033d722a9Sopenharmony_ci} 19133d722a9Sopenharmony_ci 19233d722a9Sopenharmony_ciimpl<'a> Deref for Includes<'a> { 19333d722a9Sopenharmony_ci type Target = Content<'a>; 19433d722a9Sopenharmony_ci 19533d722a9Sopenharmony_ci fn deref(&self) -> &Self::Target { 19633d722a9Sopenharmony_ci &self.content 19733d722a9Sopenharmony_ci } 19833d722a9Sopenharmony_ci} 19933d722a9Sopenharmony_ci 20033d722a9Sopenharmony_ciimpl<'a> DerefMut for Includes<'a> { 20133d722a9Sopenharmony_ci fn deref_mut(&mut self) -> &mut Self::Target { 20233d722a9Sopenharmony_ci &mut self.content 20333d722a9Sopenharmony_ci } 20433d722a9Sopenharmony_ci} 205