Squashed 'third_party/autocxx/' content from commit 629e8fa53

git-subtree-dir: third_party/autocxx
git-subtree-split: 629e8fa531a633164c0b52e2a3cab536d4cd0849
Signed-off-by: Brian Silverman <bsilver16384@gmail.com>
Change-Id: I62a03b0049f49adf029e0204639cdb5468dde1a1
diff --git a/examples/steam-mini/Cargo.toml b/examples/steam-mini/Cargo.toml
new file mode 100644
index 0000000..b292f25
--- /dev/null
+++ b/examples/steam-mini/Cargo.toml
@@ -0,0 +1,23 @@
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+# https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+# <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+[package]
+name = "autocxx-steam-example"
+version = "0.1.0"
+authors = ["Adrian Taylor <adetaylor@chromium.org>"]
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+cxx = "1.0.54"
+autocxx = { path = "../..", version="0.22.0" }
+
+[build-dependencies]
+autocxx-build = { path = "../../gen/build", version="0.22.0" }
+miette = { version="4.3", features = [ "fancy" ] }
diff --git a/examples/steam-mini/README.md b/examples/steam-mini/README.md
new file mode 100644
index 0000000..325c899
--- /dev/null
+++ b/examples/steam-mini/README.md
@@ -0,0 +1,2 @@
+This example is supposed to simulate something a bit like the Steam API,
+where you're given a pointer to a collection of virtual methods.
diff --git a/examples/steam-mini/build.rs b/examples/steam-mini/build.rs
new file mode 100644
index 0000000..d9b3c68
--- /dev/null
+++ b/examples/steam-mini/build.rs
@@ -0,0 +1,17 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() -> miette::Result<()> {
+    let path = std::path::PathBuf::from("steam/src");
+    let mut b = autocxx_build::Builder::new("src/main.rs", &[&path]).build()?;
+    b.flag_if_supported("-std=c++14")
+        .file("steam/src/steam.cc")
+        .compile("autocxx-steam-example");
+    println!("cargo:rerun-if-changed=src/main.rs");
+    Ok(())
+}
diff --git a/examples/steam-mini/src/main.rs b/examples/steam-mini/src/main.rs
new file mode 100644
index 0000000..e5d6e64
--- /dev/null
+++ b/examples/steam-mini/src/main.rs
@@ -0,0 +1,65 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use autocxx::prelude::*;
+
+include_cpp! {
+    // C++ headers we want to include.
+    #include "steam.h"
+    // Safety policy. We are marking that this whole C++ inclusion is unsafe
+    // which means the functions themselves do not need to be marked
+    // as unsafe. Other policies are possible.
+    safety!(unsafe)
+    // What types and functions we want to generate
+    generate!("GetSteamEngine")
+    generate!("IEngine")
+}
+
+fn main() {
+    // The "Steam" API gives us a void* on which we call virtual functions.
+    // This is a void*.
+    let steam_engine = ffi::GetSteamEngine();
+    // We need to know three things about this void*:
+    // 1. What is it? We know from the (fake) Steam documentation that it's
+    //    an IEngine*
+    // 2. Do we gain ownership of it? i.e. is it our responsibility to
+    //    destroy it?
+    // 3. If not, C++ presumably continues to own it. Does C++ ever destroy
+    //    it?
+    // None of these things are really encoded in the nature of a void*
+    // so you have to figure them out from the documentation.
+    //
+    // In this case, the first is easy:
+    let steam_engine = steam_engine as *mut ffi::IEngine;
+    //
+    // You then need to figure out how to expose it in Rust. Ideally, any
+    // such lifetime invariants would be handled by the compiler.
+    // If C++ is passing ownership of this object to us, and we have the
+    // prerogative to destroy it whenever we wish, then
+    // simply use [`cxx::UniquePtr::from_raw`]. If it goes out of scope in
+    // Rust the underlying C++ object will be deleted.
+    //
+    // Let's assume life is more complicated, and we must never destroy this
+    // object (because it's owned by C++). In that case, we ideally want
+    // to convert the pointer into a Rust reference with the lifetime of
+    // the program.
+    //
+    // We also have to promise to Rust that it'll never move in memory.
+    // C++ doesn't do that, so that's OK.
+    let mut steam_engine = unsafe { std::pin::Pin::new_unchecked(&mut *steam_engine) };
+    // Now we have steam_engine which is a Pin<&mut SteamEngine>
+    // Each time we call a method we need to add `as_mut()`
+    // as per the pattern explained in
+    // https://doc.rust-lang.org/std/pin/struct.Pin.html#method.as_mut
+    steam_engine
+        .as_mut()
+        .ConnectToGlobalUser(autocxx::c_int(12));
+    steam_engine
+        .as_mut()
+        .DisconnectGlobalUser(autocxx::c_int(12));
+}
diff --git a/examples/steam-mini/steam/src/steam.cc b/examples/steam-mini/steam/src/steam.cc
new file mode 100644
index 0000000..2c45488
--- /dev/null
+++ b/examples/steam-mini/steam/src/steam.cc
@@ -0,0 +1,28 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#include <iostream>
+#include "steam.h"
+
+// This is a simulation of _something like_ the way the steam API works.
+// None of this code is really from Steam.
+
+class SteamEngine : public IEngine {
+    int ConnectToGlobalUser(int user_id) {
+        std::cout << "ConnectToGlobalUser, passed " << user_id << std::endl;
+        return 42;
+    }
+    void DisconnectGlobalUser(int user_id) {
+        std::cout << "DisconnectGlobalUser, passed " << user_id << std::endl;
+    }
+};
+
+void* GetSteamEngine() {
+    return new SteamEngine();
+}
+
diff --git a/examples/steam-mini/steam/src/steam.h b/examples/steam-mini/steam/src/steam.h
new file mode 100644
index 0000000..f07aee3
--- /dev/null
+++ b/examples/steam-mini/steam/src/steam.h
@@ -0,0 +1,19 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#pragma once
+
+// This is a simulation of _something like_ the way the steam API works.
+
+class IEngine {
+public:
+	virtual int ConnectToGlobalUser(int) = 0;
+    virtual void DisconnectGlobalUser(int user_id) = 0;
+};
+
+void* GetSteamEngine(); // return an IEngine*