1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
//! Crate to `#include` C++ headers in your Rust code, and generate
//! idiomatic bindings using `cxx`. See [include_cpp] for details.

// Copyright 2020 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.

// The crazy macro_rules magic in this file is thanks to dtolnay@
// and is a way of attaching rustdoc to each of the possible directives
// within the include_cpp outer macro. None of the directives actually
// do anything - all the magic is handled entirely by
// autocxx_macro::include_cpp_impl.

#[allow(unused_imports)] // doc cross-reference only
use autocxx_engine::IncludeCppEngine;

#[cfg_attr(doc, aquamarine::aquamarine)]
/// Include some C++ headers in your Rust project.
///
/// This macro allows you to include one or more C++ headers within
/// your Rust code, and call their functions fairly naturally.
///
/// # Examples
///
/// C++ header (`input.h`):
/// ```cpp
/// #include <cstdint>
///
/// uint32_t do_math(uint32_t a);
/// ```
///
/// Rust code:
/// ```
/// # use autocxx_macro::include_cpp_impl as include_cpp;
/// include_cpp!(
/// #   parse_only!()
///     #include "input.h"
///     generate!("do_math")
///     safety!(unsafe)
/// );
///
/// # mod ffi { pub fn do_math(a: u32) -> u32 { a+3 } }
/// # fn main() {
/// ffi::do_math(3);
/// # }
/// ```
///
/// The resulting bindings will use idiomatic Rust wrappers for types from the [cxx]
/// crate, for example [cxx::UniquePtr] or [cxx::CxxString]. Due to the care and thought
/// that's gone into the [cxx] crate, such bindings are pleasant and idiomatic to use
/// from Rust, and usually don't require the `unsafe` keyword.
///
/// # User manual - introduction
///
/// [include_cpp] tries to make it possible to include C++ headers and use declared functions
/// and types as-is. The resulting bindings use wrappers for C++ STL types from the [cxx]
/// crate such as [cxx::UniquePtr] or [cxx::CxxString].
///
/// Why, then, do you need a manual? Three reasons:
///
/// * This manual will describe how to include `autocxx` in your build process.
/// * `autocxx` chooses to generate Rust bindings for C++ APIs in particular ways,
///   over which you have _some_ control. The manual discusses what and how.
/// * The combination of `autocxx` and [cxx] are not perfect. There are some STL
///   types and some fundamental C++ features which are not yet supported. Where that occurs,
///   you may need to create some manual bindings or otherwise workaround deficiencies.
///   This manual tells you how to spot such circumstances and work around them.
///
/// # Overview
///
/// Here's how to approach autocxx:
///
/// ```mermaid
/// flowchart TB
///     %%{init:{'flowchart':{'nodeSpacing': 60, 'rankSpacing': 30}}}%%
///     autocxx[Add a dependency on autocxx in your project]
///     which-build([Do you use cargo?])
///     autocxx--->which-build
///     autocxx-build[Add a dev dependency on autocxx-build]
///     build-rs[In your build.rs, tell autocxx-build about your header include path]
///     autocxx-build--->build-rs
///     which-build-- Yes -->autocxx-build
///     macro[Add include_cpp! macro: list headers and allowlist]
///     build-rs--->macro
///     autocxx-gen[Use autocxx-gen command line tool]
///     which-build-- No -->autocxx-gen
///     autocxx-gen--->macro
///     build[Build]
///     macro--->build
///     check[Confirm generation using cargo expand]
///     build--->check
///     manual[Add manual cxx::bridge for anything missing]
///     check--->manual
///     use[Use generated ffi mod APIs]
///     manual--->use
/// ```
///
/// # Configuring the build - if you're using cargo
///
/// You'll use the `autocxx-build` crate. Simply copy from the
/// [demo example](https://github.com/google/autocxx/blob/main/demo/build.rs).
/// You'll need to provide it:
/// * The list of `.rs` files which will have `include_cpp!` macros present
/// * Your C++ header include path.
///
/// # Configuring the build - if you're not using cargo
///
/// See the `autocxx-gen` crate. You'll need to:
///
/// * Run the `codegen` phase. You'll need to use the [autocxx-gen]
///   tool to process the .rs code into C++ header and
///   implementation files. This will also generate `.rs` side bindings.
/// * Educate the procedural macro about where to find the generated `.rs` bindings. Set the
///   `AUTOCXX_RS` environment variable to a list of directories to search.
///   If you use `autocxx-build`, this happens automatically. (You can alternatively
///   specify `AUTOCXX_RS_FILE` to give a precise filename as opposed to a directory to search,
///   though this isn't recommended unless your build system specifically requires it
///   because it allows only a single `include_cpp!` block per `.rs` file.)
///
/// ```mermaid
/// flowchart TB
///     s(Rust source with include_cpp!)
///     c(Existing C++ headers)
///     cg(autocxx-gen or autocxx-build)
///     genrs(Generated .rs file)
///     gencpp(Generated .cpp and .h files)
///     rsb(Rust/Cargo build)
///     cppb(C++ build)
///     l(Linker)
///     s --> cg
///     c --> cg
///     cg --> genrs
///     cg --> gencpp
///     m(autocxx-macro)
///     s --> m
///     genrs-. included .->m
///     m --> rsb
///     gencpp --> cppb
///     cppb --> l
///     rsb --> l
/// ```
///
/// # The `include_cpp` macro
///
/// Within the braces of the `include_cpp!{...}` macro, you should provide
/// a list of at least the following:
///
/// * `#include "cpp_header.h"`: a header filename to parse and include
/// * `generate!("type_or_function_name")`: a type or function name whose declaration
///   should be made available to C++.
/// * Optionally, `safety!(unsafe)` - see discussion of [`safety`].
///
/// Other directives are possible as documented in this crate.
///
/// Now, try to build your Rust project. `autocxx` may fail to generate bindings
/// for some of the items you specified with [generate] directives: remove
/// those directives for now, then see the next section for advice.
///
/// # Did it work? How do I deal with failure?
///
/// Once you've achieved a successful build, you might wonder how to know what
/// bindings have been generated. `cargo expand` will show you. In the (near) future,
/// it's hoped that `rust-analyzer` will gain support for expanding procedural
/// macros and you'll be able to see the bindings from Rust IDEs.
///
/// Either way, you'll find (for sure!) that `autocxx` hasn't been able to generate
/// bindings for all your C++ APIs. This may manifest as a hard failure or a soft
/// failure:
/// * If you specified such an item in a [`generate`] directive (or similar such
///   as [`generate_pod`]) then your build will fail.
/// * If such APIs are methods belonging to a type, `autocxx` will generate other
///   methods for the type but ignore those.
///
/// In this latter case, you should see helpful messages _in the generated bindings_
/// as rust documentation explaining what went wrong.
///
/// If this happens (and it will!) your options are:
/// * Add more, simpler C++ APIs which fulfil the same need but are compatible with
///   `autocxx`.
/// * Write manual bindings. This is most useful if a type is supported by [cxx]
///   but not `autocxx` (for example, at the time of writing `std::array`). See
///   the later section on 'combinining automatic and manual bindings'.
///
/// # The generated bindings
///
/// ## Pointers, references, and so-forth
///
/// `autocxx` knows how to deal with C++ APIs which take C++ types:
/// * By value
/// * By reference (const or not)
/// * By raw pointer
/// * By `std::unique_ptr`
/// * By `std::shared_ptr`
/// * By `std::weak_ptr`
///
/// (all of this is because the underlying [cxx] crate has such versatility).
/// Some of these have some quirks in the way they're exposed in Rust, described below.
///
/// ### Passing between C++ and Rust by value
///
/// Rust is free to move data around at any time. That's _not OK_ for some C++ types
/// which have non-trivial move constructors or destructors. Such types are common
/// in C++ (for example, even C++ `std::string`s) and these types commonly appear
/// in API declarations which we want to make available in Rust. Worse still, Rust
/// has no visibility into whether a C++ type meets these criteria. What do we do?
///
/// You have a choice:
/// * As standard, any C++ type passed by value will be `std::move`d on the C++ side
///   into a `std::unique_ptr` before being passed to Rust, and similarly moved out
///   of a `std::unique_ptr` when passed from Rust to C++.
/// * If you know that your C++ type can be safely byte-copied, then you can
///   override this behavior by using [`generate_pod`] instead of [`generate`].
///
/// There's not a significant ergonomic problem from the use of [`cxx::UniquePtr`].
/// The main negative of the automatic boxing into [`cxx::UniquePtr`] is performance:
/// specifiaclly, the need to
/// allocate heap cells on the C++ side and move data into and out of them.
/// You don't want to be doing this inside a tight loop (but if you're calling
/// across the C++/Rust boundary in a tight loop, perhaps reconsider that boundary
/// anyway).
///
/// If you want your type to be transferred between Rust and C++ truly _by value_
/// then use [`generate_pod`] instead of [`generate`].
///
/// Specifically, to be compatible with [`generate_pod`], your C++ type must either:
/// * Lack a move constructor _and_ lack a destructor
/// * Or contain a human promise that it's relocatable, by implementing
///   the C++ trait `IsRelocatable` per the instructions in
///   [cxx.h](https://github.com/dtolnay/cxx/blob/master/include/cxx.h)
///
/// Otherwise, your build will fail.
///
/// This doesn't just make a difference to the generated code for the type;
/// it also makes a difference to any functions which take or return that type.
/// If there's a C++ function which takes a struct by value, but that struct
/// is not declared as POD-safe, then we'll generate wrapper functions to move
/// that type into and out of [`cxx::UniquePtr`]s.
///
/// ### References and pointers
///
/// We follow [cxx] norms here. Specifically:
/// * A C++ reference becomes a Rust reference
/// * A C++ pointer becomes a Rust pointer.
/// * If a reference is returned with an ambiguous lifetime, we don't generate
///   code for the function
/// * Pointers require use of `unsafe`, references don't necessarily.
///
/// That last point is key. If your C++ API takes pointers, you're going
/// to have to use `unsafe`. Similarly, if your C++ API returns a pointer,
/// you'll have to use `unsafe` to do anything useful with the pointer in Rust.
/// This is intentional: a pointer from C++ might be subject to concurrent
/// mutation, or it might have a lifetime that could disappear at any moment.
/// As a human, you must promise that you understand the constraints around
/// use of that pointer and that's what the `unsafe` keyword is for.
///
/// Exactly the same issues apply to C++ references _in theory_, but in practice,
/// they usually don't. Therefore [cxx] has taken the view that we can "trust"
/// a C++ reference to a higher degree than a pointer, and autocxx follows that
/// lead. In practice, of course, references are rarely return values from C++
/// APIs so we rarely have to navel-gaze about the trustworthiness of a
/// reference.
///
/// (See also the discussion of [`safety`] - if you haven't specified
/// an unsafety policy, _all_ C++ APIs require `unsafe` so the discussion is moot.)
///
/// ### [`cxx::UniquePtr`]s
///
/// We use [`cxx::UniquePtr`] in completely the normal way, but there are a few
/// quirks which you're more likely to run into with `autocxx`.
///
/// * Calling methods: you may need to use [`cxx::UniquePtr::pin_mut`] to get
///   a reference on which you can call a method.
/// * Getting a raw pointer in order to pass to some pre-existing function:
///   at present you need to do:
///   ```rust,ignore
///      let mut a = ffi::A::make_unique();
///      unsafe { ffi::TakePointerToA(std::pin::Pin::<&mut ffi::A>::into_inner_unchecked(a.pin_mut())) };
///   ```
///   This may be simplified in future.
///
/// ## Construction
///
/// Types gain a `make_unique` associated function. At present they only
/// gain this if they have an explicit C++ constructor; this is a limitation
/// which should be resolved in future.
/// This will (of course) return a [`cxx::UniquePtr`] containing that type.
///
/// ## Built-in types
///
/// The generated code uses `cxx` for interop: see that crate for many important
/// considerations including safety and the list of built-in types, for example
/// [`cxx::UniquePtr`] and [`cxx::CxxString`].
///
/// There are almost no `autocxx`-specific types. At present, we do have
/// [`c_int`] and similar, to wrap the integer types whose length
/// varies in C++. It's hoped to contribute full support here to [cxx]
/// in a future change.
///
/// ## Strings
///
/// `autocxx` uses [cxx::CxxString]. However, as noted above, we can't
/// just pass a C++ string by value, so we'll box and unbox it automatically
/// such that you're really dealing with `UniquePtr<CxxString>` on the Rust
/// side, even if the API just took or returned a plain old `std::string`.
///
/// However, to ease ergonomics, functions that accept a `std::string` will
/// actually accept anything that
/// implements a trait called `ffi::ToCppString`. That may either be a
/// `UniquePtr<CxxString>` or just a plain old Rust string - which will be
/// converted transparently to a C++ string.
///
/// This trait, and its implementations, are not present in the `autocxx`
/// documentation because they're dynamically generated in _your_ code
/// so that they can call through to a `make_string` implementation in
/// the C++ that we're injecting into your C++ build system.
///
/// (None of that happens if you use [exclude_utilities], so don't do that.)
///
/// If you need to create a blank `UniquePtr<CxxString>` in Rust, such that
/// (for example) you can pass its mutable reference or pointer into some
/// pre-existing C++ API, there's currently no built in support for that.
/// You should add an extra C++ API:
///
/// ```cpp
/// std::string make_blank_string() { return std::string(); }
/// ```
///
/// and then use [`generate`] to make bindings for that.
///
/// ## Preprocessor symbols
///
/// `#define` and other preprocessor symbols will appear as constants.
/// At present there is no way to do compile-time disablement of code
/// (equivalent of `#ifdef`).
///
/// ## Integer types
///
/// For C++ types with a defined size, just go ahead and use `u64`, `i32` etc.
/// For types such as `int` or `unsigned long`, the hope is that you can
/// eventually use `std::os::raw::c_int` oor `std::os::raw::c_ulong` etc.
/// For now, this doesn't quite work: instead you need to wrap these values
/// in a newtype wrapper such as [c_int] or [c_ulong] in this crate.
///
/// ## String constants
///
/// Whether from a preprocessor symbol or from a C++ `char*` constant,
/// strings appear as `[u8]` with a null terminator. To get a Rust string,
/// do this:
///
/// ```cpp
/// #define BOB "Hello"
/// ```
///
/// ```
/// # mod ffi { pub static BOB: [u8; 6] = [72u8, 101u8, 108u8, 108u8, 111u8, 0u8]; }
/// assert_eq!(std::str::from_utf8(&ffi::BOB).unwrap().trim_end_matches(char::from(0)), "Hello");
/// ```
///
/// ## Namespaces
///
/// The C++ namespace structure is reflected in mods within the generated
/// ffi mod. However, at present there is an internal limitation that
/// autocxx can't handle multiple symbols with the same identifier, even
/// if they're in different namespaces. This will be fixed in future.
///
/// ## Overloads - and identifiers ending in digits
///
/// C++ allows function overloads; Rust doesn't. `autocxx` follows the lead
/// of `bindgen` here and generating overloads as `func`, `func1`, `func2` etc.
/// This is essentially awful without `rust-analyzer` IDE support, which isn't
/// quite there yet.
///
/// `autocxx` doesn't yet support default paramters.
///
/// ## Forward declarations
///
/// A type which is incomplete in the C++ headers (i.e. represented only by a forward
/// declaration) can't be held in a `UniquePtr` within Rust (because Rust can't know
/// if it has a destructor that will need to be called if the object is `Drop`ped.)
/// Naturally, such an object can't be passed by value either; it can still be
/// referenced in Rust references.
///
/// ## Generic types
///
/// If you're using one of the generic types which is supported natively by cxx,
/// e.g. `std::unique_ptr`, it should work as you expect. For other generic types,
/// we synthesize a concrete Rust type, corresponding to a C++ typedef, for each
/// concrete instantiation of the type. Such generated types are always opaque,
/// and never have methods attached. That's therefore enough to pass them
/// between return types and parameters of other functions within [`cxx::UniquePtr`]s
/// but not really enough to do anything else with these types just yet. Hopefully,
/// this will be improved in future. At present such types have a name
/// `AutocxxConcrete{n}` but this may change in future.
///
/// ## Exceptions
///
/// Exceptions are not supported. If your C++ code is compiled with exceptions,
/// you can expect serious runtime explosions. The underlying [cxx] crate has
/// exception support, so it would be possible to add them.
///
/// # Mixing manual and automated bindings
///
/// `autocxx` uses [cxx] underneath, and its build process will happily spot and
/// process and manually-crafted [`cxx::bridge`] mods which you include in your
/// Rust source code. A common pattern good be to use `autocxx` to generate
/// all the bindings possible, then hand-craft a [`cxx::bridge`] mod for the
/// remainder where `autocxx` falls short.
///
/// To do this, you'll need to use the [ability of one cxx::bridge mod to refer to types from another](https://cxx.rs/extern-c++.html#reusing-existing-binding-types),
/// for example:
///
/// ```rust,ignore
/// autocxx::include_cpp! {
///     #include "foo.h"
///     safety!(unsafe_ffi)
///     generate!("take_A")
///     generate!("A")
/// }
/// #[cxx::bridge]
/// mod ffi2 {
///     unsafe extern "C++" {
///         include!("foo.h");
///         type A = crate::ffi::A;
///         fn give_A() -> UniquePtr<A>; // in practice, autocxx could happily do this
///     }
/// }
/// fn main() {
///     let a = ffi2::give_A();
///     assert_eq!(ffi::take_A(&a), autocxx::c_int(5));
/// }
/// ```
///
/// # Safety
///
/// # Examples
///
/// * [Demo](https://github.com/google/autocxx/tree/main/demo) - simplest possible demo
/// * [S2 example](https://github.com/google/autocxx/tree/main/examples/s2) - example using S2 geometry library
/// * [Integration tests](https://github.com/google/autocxx/blob/main/engine/src/integration_tests.rs)
///   - hundreds of small snippets
///
/// Contributions of more examples to the `examples` directory are much appreciated!
///
/// # Internals
///
/// For documentation on how this all actually _works_, see
/// [IncludeCppEngine].
#[macro_export]
macro_rules! include_cpp {
    (
        $(#$include:ident $lit:literal)*
        $($mac:ident!($($arg:tt)*))*
    ) => {
        $($crate::$include!{__docs})*
        $($crate::$mac!{__docs})*
        $crate::include_cpp_impl! {
            $(#include $lit)*
            $($mac!($($arg)*))*
        }
    };
}

/// Include a C++ header. A directive to be included inside
/// [include_cpp] - see [include_cpp] for details
#[macro_export]
macro_rules! include {
    ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
}

/// Generate Rust bindings for the given C++ type or function.
/// A directive to be included inside
/// [include_cpp] - see [include_cpp] for general information.
/// See also [generate_pod].
#[macro_export]
macro_rules! generate {
    ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
}

/// Generate as "plain old data" and add to allowlist.
/// Generate Rust bindings for the given C++ type such that
/// it can be passed and owned by value in Rust. This only works
/// for C++ types which have trivial move constructors and no
/// destructor - you'll encounter a compile error otherwise.
/// If your type doesn't match that description, use [generate]
/// instead, and own the type using [UniquePtr][autocxx_engine::cxx::UniquePtr].
/// A directive to be included inside
/// [include_cpp] - see [include_cpp] for general information.
#[macro_export]
macro_rules! generate_pod {
    ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
}

/// Generate Rust bindings for all C++ types and functions
/// found. Highly experimental and not recommended.
/// A directive to be included inside
/// [include_cpp] - see [include_cpp] for general information.
/// See also [generate].
#[macro_export]
macro_rules! generate_all {
    ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
}

/// Generate as "plain old data". For use with [generate_all]
/// and similarly experimental.
#[macro_export]
macro_rules! pod {
    ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
}

/// Skip the normal generation of a `make_string` function
/// and other utilities which we might generate normally.
/// A directive to be included inside
/// [include_cpp] - see [include_cpp] for general information.
#[macro_export]
macro_rules! exclude_utilities {
    ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
}

/// Entirely block some type from appearing in the generated
/// code. This can be useful if there is a type which is not
/// understood by bindgen or autocxx, and incorrect code is
/// otherwise generated.
/// This is 'greedy' in the sense that any functions/methods
/// which take or return such a type will _also_ be blocked.
///
/// A directive to be included inside
/// [include_cpp] - see [include_cpp] for general information.
#[macro_export]
macro_rules! block {
    ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
}

/// The name of the mod to be generated with the FFI code.
/// The default is `ffi`.
///
/// A directive to be included inside
/// [include_cpp] - see [include_cpp] for general information.
#[macro_export]
macro_rules! name {
    ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
}

/// Specifies a global safety policy for functions generated
/// from these headers. By default (without such a `safety!`
/// directive) all such functions are marked as `unsafe` and
/// therefore can only be called within an `unsafe {}` block
/// or some `unsafe` function which you create.
///
/// Alternatively, by specifying a `safety!` block you can
/// declare that most generated functions are in fact safe.
/// Specifically, you'd specify:
/// `safety!(unsafe)`
/// or
/// `safety!(unsafe_ffi)`
/// These two options are functionally identical. If you're
/// unsure, simply use `unsafe`. The reason for the
/// latter option is if you have code review policies which
/// might want to give a different level of scrutiny to
/// C++ interop as opposed to other types of unsafe Rust code.
/// Maybe in your organization, C++ interop is less scary than
/// a low-level Rust data structure using pointer manipulation.
/// Or maybe it's more scary. Either way, using `unsafe` for
/// the data structure and using `unsafe_ffi` for the C++
/// interop allows you to apply different linting tools and
/// policies to the different options.
///
/// Irrespective, C++ code is of course unsafe. It's worth
/// noting that use of C++ can cause unexpected unsafety at
/// a distance in faraway Rust code. As with any use of the
/// `unsafe` keyword in Rust, *you the human* are declaring
/// that you've analyzed all possible ways that the code
/// can be used and you are guaranteeing to the compiler that
/// no badness can occur. Good luck.
///
/// Generated C++ APIs which use raw pointers remain `unsafe`
/// no matter what policy you choose.
#[macro_export]
macro_rules! safety {
    ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
}

/// Whether to avoid generating [`cxx::UniquePtr`] and [`cxx::Vector`]
/// implementations. This is primarily useful for reducing test cases and
/// shouldn't be used in normal operation.
///
/// A directive to be included inside
/// [include_cpp] - see [include_cpp] for general information.
#[macro_export]
macro_rules! exclude_impls {
    ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
}

#[doc(hidden)]
#[macro_export]
macro_rules! usage {
    (__docs) => {};
    ($($tt:tt)*) => {
        compile_error! {r#"usage:  include_cpp! {
                   #include "path/to/header.h"
                   generate!(...)
                   generate_pod!(...)
               }
"#}
    };
}

#[doc(hidden)]
pub use autocxx_macro::include_cpp_impl;

macro_rules! ctype_wrapper {
    ($r:ident, $c:expr, $d:expr) => {
        #[doc=$d]
        #[derive(Debug, Eq, Clone, PartialEq, Hash)]
        #[allow(non_camel_case_types)]
        #[repr(transparent)]
        pub struct $r(pub ::std::os::raw::$r);

        unsafe impl autocxx_engine::cxx::ExternType for $r {
            type Id = autocxx_engine::cxx::type_id!($c);
            type Kind = autocxx_engine::cxx::kind::Trivial;
        }
    };
}

ctype_wrapper!(
    c_ulonglong,
    "c_ulonglong",
    "Newtype wrapper for an unsigned long long"
);
ctype_wrapper!(c_longlong, "c_longlong", "Newtype wrapper for a long long");
ctype_wrapper!(c_ulong, "c_ulong", "Newtype wrapper for an unsigned long");
ctype_wrapper!(c_long, "c_long", "Newtype wrapper for a long");
ctype_wrapper!(
    c_ushort,
    "c_ushort",
    "Newtype wrapper for an unsigned short"
);
ctype_wrapper!(c_short, "c_short", "Newtype wrapper for an short");
ctype_wrapper!(c_uint, "c_uint", "Newtype wrapper for an unsigned int");
ctype_wrapper!(c_int, "c_int", "Newtype wrapper for an int");
ctype_wrapper!(c_uchar, "c_uchar", "Newtype wrapper for an unsigned char");

/// Newtype wrapper for a C void. Only useful as a `*c_void`
#[allow(non_camel_case_types)]
#[repr(transparent)]
pub struct c_void(pub ::std::os::raw::c_void);

unsafe impl autocxx_engine::cxx::ExternType for c_void {
    type Id = autocxx_engine::cxx::type_id!(c_void);
    type Kind = autocxx_engine::cxx::kind::Trivial;
}

/// autocxx couldn't generate these bindings.
/// If you come across a method, type or function which refers to this type,
/// it indicates that autocxx couldn't generate that binding. A documentation
/// comment should be attached indicating the reason.
pub struct BindingGenerationFailure {
    _unallocatable: [*const u8; 0],
    _pinned: core::marker::PhantomData<core::marker::PhantomPinned>,
}