| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 1 | use crate::gen::out::{Content, OutFile}; |
| David Tolnay | 353d98c | 2020-10-28 15:43:35 -0700 | [diff] [blame] | 2 | use crate::syntax::{self, IncludeKind}; |
| David Tolnay | 8810a54 | 2020-10-31 21:39:22 -0700 | [diff] [blame] | 3 | use std::ops::{Deref, DerefMut}; |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 4 | |
| David Tolnay | 0e01d64 | 2020-10-16 12:54:44 -0700 | [diff] [blame] | 5 | /// The complete contents of the "rust/cxx.h" header. |
| David Tolnay | 736cbca | 2020-03-11 16:49:18 -0700 | [diff] [blame] | 6 | pub static HEADER: &str = include_str!("include/cxx.h"); |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 7 | |
| David Tolnay | 700cd0c | 2020-10-28 12:40:27 -0700 | [diff] [blame] | 8 | /// A header to #include. |
| 9 | /// |
| 10 | /// The cxxbridge tool does not parse or even require the given paths to exist; |
| 11 | /// they simply go into the generated C++ code as #include lines. |
| 12 | #[derive(Clone, PartialEq, Debug)] |
| David Tolnay | 4aae7c0 | 2020-10-28 12:35:42 -0700 | [diff] [blame] | 13 | pub struct Include { |
| David Tolnay | 700cd0c | 2020-10-28 12:40:27 -0700 | [diff] [blame] | 14 | /// The header's path, not including the enclosing quotation marks or angle |
| 15 | /// brackets. |
| David Tolnay | 4aae7c0 | 2020-10-28 12:35:42 -0700 | [diff] [blame] | 16 | pub path: String, |
| David Tolnay | 700cd0c | 2020-10-28 12:40:27 -0700 | [diff] [blame] | 17 | /// Whether to emit `#include "path"` or `#include <path>`. |
| David Tolnay | 4aae7c0 | 2020-10-28 12:35:42 -0700 | [diff] [blame] | 18 | pub kind: IncludeKind, |
| 19 | } |
| 20 | |
| David Tolnay | 3577d45 | 2020-03-17 21:48:13 -0700 | [diff] [blame] | 21 | #[derive(Default, PartialEq)] |
| David Tolnay | 97c5b86 | 2020-11-01 14:59:01 -0800 | [diff] [blame] | 22 | pub struct Includes<'a> { |
| David Tolnay | 12af7e4 | 2020-10-31 21:09:23 -0700 | [diff] [blame] | 23 | pub custom: Vec<Include>, |
| David Tolnay | f799b37 | 2020-11-29 23:57:42 -0800 | [diff] [blame] | 24 | pub algorithm: bool, |
| David Tolnay | b7a7cb6 | 2020-03-17 21:18:40 -0700 | [diff] [blame] | 25 | pub array: bool, |
| David Tolnay | 30430f1 | 2020-03-19 20:49:00 -0700 | [diff] [blame] | 26 | pub cstddef: bool, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 27 | pub cstdint: bool, |
| David Tolnay | ebef4a2 | 2020-03-17 15:33:47 -0700 | [diff] [blame] | 28 | pub cstring: bool, |
| David Tolnay | b7a7cb6 | 2020-03-17 21:18:40 -0700 | [diff] [blame] | 29 | pub exception: bool, |
| David Tolnay | f799b37 | 2020-11-29 23:57:42 -0800 | [diff] [blame] | 30 | pub initializer_list: bool, |
| David Tolnay | d1df4c7 | 2020-11-25 20:38:05 -0800 | [diff] [blame] | 31 | pub iterator: bool, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 32 | pub memory: bool, |
| David Tolnay | 0ecd05a | 2020-07-29 16:32:03 -0700 | [diff] [blame] | 33 | pub new: bool, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 34 | pub string: bool, |
| 35 | pub type_traits: bool, |
| David Tolnay | 4791f1c | 2020-03-17 21:53:16 -0700 | [diff] [blame] | 36 | pub utility: bool, |
| David Tolnay | 8b7f899 | 2020-04-25 13:06:08 -0700 | [diff] [blame] | 37 | pub vector: bool, |
| David Tolnay | da38b7c | 2020-09-16 11:50:04 -0400 | [diff] [blame] | 38 | pub basetsd: bool, |
| David Tolnay | 97c5b86 | 2020-11-01 14:59:01 -0800 | [diff] [blame] | 39 | pub content: Content<'a>, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 40 | } |
| 41 | |
| David Tolnay | 97c5b86 | 2020-11-01 14:59:01 -0800 | [diff] [blame] | 42 | impl<'a> Includes<'a> { |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 43 | pub fn new() -> Self { |
| 44 | Includes::default() |
| 45 | } |
| 46 | |
| David Tolnay | 353d98c | 2020-10-28 15:43:35 -0700 | [diff] [blame] | 47 | pub fn insert(&mut self, include: impl Into<Include>) { |
| 48 | self.custom.push(include.into()); |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 49 | } |
| 50 | } |
| 51 | |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 52 | pub(super) fn write(out: &mut OutFile) { |
| David Tolnay | 58711a9 | 2020-11-01 19:11:37 -0800 | [diff] [blame] | 53 | let header = out.header; |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 54 | let include = &mut out.include; |
| 55 | let out = &mut include.content; |
| 56 | |
| David Tolnay | 58711a9 | 2020-11-01 19:11:37 -0800 | [diff] [blame] | 57 | if header { |
| 58 | writeln!(out, "#pragma once"); |
| 59 | } |
| 60 | |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 61 | for include in &include.custom { |
| 62 | match include.kind { |
| 63 | IncludeKind::Quoted => { |
| 64 | writeln!(out, "#include \"{}\"", include.path.escape_default()); |
| 65 | } |
| 66 | IncludeKind::Bracketed => { |
| 67 | writeln!(out, "#include <{}>", include.path); |
| 68 | } |
| 69 | } |
| 70 | } |
| 71 | |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 72 | let Includes { |
| 73 | custom: _, |
| David Tolnay | f799b37 | 2020-11-29 23:57:42 -0800 | [diff] [blame] | 74 | algorithm, |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 75 | array, |
| 76 | cstddef, |
| 77 | cstdint, |
| 78 | cstring, |
| 79 | exception, |
| David Tolnay | f799b37 | 2020-11-29 23:57:42 -0800 | [diff] [blame] | 80 | initializer_list, |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 81 | iterator, |
| 82 | memory, |
| 83 | new, |
| 84 | string, |
| 85 | type_traits, |
| 86 | utility, |
| 87 | vector, |
| 88 | basetsd, |
| 89 | content: _, |
| 90 | } = *include; |
| 91 | |
| David Tolnay | f799b37 | 2020-11-29 23:57:42 -0800 | [diff] [blame] | 92 | if algorithm { |
| 93 | writeln!(out, "#include <algorithm>"); |
| 94 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 95 | if array { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 96 | writeln!(out, "#include <array>"); |
| 97 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 98 | if cstddef { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 99 | writeln!(out, "#include <cstddef>"); |
| 100 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 101 | if cstdint { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 102 | writeln!(out, "#include <cstdint>"); |
| 103 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 104 | if cstring { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 105 | writeln!(out, "#include <cstring>"); |
| 106 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 107 | if exception { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 108 | writeln!(out, "#include <exception>"); |
| 109 | } |
| David Tolnay | f799b37 | 2020-11-29 23:57:42 -0800 | [diff] [blame] | 110 | if initializer_list { |
| 111 | writeln!(out, "#include <initializer_list>"); |
| 112 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 113 | if iterator { |
| David Tolnay | d1df4c7 | 2020-11-25 20:38:05 -0800 | [diff] [blame] | 114 | writeln!(out, "#include <iterator>"); |
| 115 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 116 | if memory { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 117 | writeln!(out, "#include <memory>"); |
| 118 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 119 | if new { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 120 | writeln!(out, "#include <new>"); |
| 121 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 122 | if string { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 123 | writeln!(out, "#include <string>"); |
| 124 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 125 | if type_traits { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 126 | writeln!(out, "#include <type_traits>"); |
| 127 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 128 | if utility { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 129 | writeln!(out, "#include <utility>"); |
| 130 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 131 | if vector { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 132 | writeln!(out, "#include <vector>"); |
| 133 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 134 | if basetsd { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 135 | writeln!(out, "#if defined(_WIN32)"); |
| 136 | writeln!(out, "#include <basetsd.h>"); |
| 137 | writeln!(out, "#endif"); |
| 138 | } |
| 139 | } |
| 140 | |
| David Tolnay | 97c5b86 | 2020-11-01 14:59:01 -0800 | [diff] [blame] | 141 | impl<'i, 'a> Extend<&'i Include> for Includes<'a> { |
| 142 | fn extend<I: IntoIterator<Item = &'i Include>>(&mut self, iter: I) { |
| David Tolnay | 700cd0c | 2020-10-28 12:40:27 -0700 | [diff] [blame] | 143 | self.custom.extend(iter.into_iter().cloned()); |
| David Tolnay | 33d3029 | 2020-03-18 18:02:02 -0700 | [diff] [blame] | 144 | } |
| 145 | } |
| 146 | |
| David Tolnay | 97c5b86 | 2020-11-01 14:59:01 -0800 | [diff] [blame] | 147 | impl<'i> From<&'i syntax::Include> for Include { |
| David Tolnay | 353d98c | 2020-10-28 15:43:35 -0700 | [diff] [blame] | 148 | fn from(include: &syntax::Include) -> Self { |
| 149 | Include { |
| 150 | path: include.path.clone(), |
| 151 | kind: include.kind, |
| 152 | } |
| 153 | } |
| 154 | } |
| David Tolnay | 8810a54 | 2020-10-31 21:39:22 -0700 | [diff] [blame] | 155 | |
| David Tolnay | 97c5b86 | 2020-11-01 14:59:01 -0800 | [diff] [blame] | 156 | impl<'a> Deref for Includes<'a> { |
| 157 | type Target = Content<'a>; |
| David Tolnay | 8810a54 | 2020-10-31 21:39:22 -0700 | [diff] [blame] | 158 | |
| 159 | fn deref(&self) -> &Self::Target { |
| 160 | &self.content |
| 161 | } |
| 162 | } |
| 163 | |
| David Tolnay | 97c5b86 | 2020-11-01 14:59:01 -0800 | [diff] [blame] | 164 | impl<'a> DerefMut for Includes<'a> { |
| David Tolnay | 8810a54 | 2020-10-31 21:39:22 -0700 | [diff] [blame] | 165 | fn deref_mut(&mut self) -> &mut Self::Target { |
| 166 | &mut self.content |
| 167 | } |
| 168 | } |