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/subclass/src/billy.rs b/examples/subclass/src/billy.rs
new file mode 100644
index 0000000..5defe1b
--- /dev/null
+++ b/examples/subclass/src/billy.rs
@@ -0,0 +1,20 @@
+// 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.
+
+pub(crate) static SHAKESPEARE_QUOTES: [&str; 10] = [
+    "All that glitters is not gold",
+    "Hell is empty and all the devils are here.",
+    "Good night, good night! parting is such sweet sorrow, That I shall say good night till it be morrow.",
+    "These violent delights have violent ends...",
+    "Something is rotten in the state of Denmark.",
+    "Love all, trust a few, do wrong to none.",
+    "The lady doth protest too much, methinks.",
+    "Brevity is the soul of wit.",
+    "Uneasy lies the head that wears a crown.",
+    "Now is the winter of our discontent.",
+];
diff --git a/examples/subclass/src/main.rs b/examples/subclass/src/main.rs
new file mode 100644
index 0000000..2841598
--- /dev/null
+++ b/examples/subclass/src/main.rs
@@ -0,0 +1,145 @@
+// 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.
+
+// This example shows some Rust subclasses of C++ classes.
+
+mod billy;
+mod uwu;
+
+use autocxx::prelude::*;
+use autocxx::subclass::prelude::*;
+use cxx::CxxString;
+use std::cell::RefCell;
+use std::rc::Rc;
+
+include_cpp! {
+    #include "messages.h"
+    safety!(unsafe) // unsafety policy; see docs
+}
+
+// Here's the definition of MessageDisplayer from src/messages.h:
+// ```cpp
+// class MessageDisplayer {
+// public:
+//     virtual void display_message(const std::string& message) const = 0;
+//     virtual ~MessageDisplayer() {};
+// };
+// ```
+// The following lines define a subclass of MessageDisplayer.
+// See the main function at the bottom for how this subclass
+// is instantiated.
+
+#[is_subclass(superclass("MessageDisplayer"))]
+#[derive(Default)]
+pub struct UwuDisplayer {}
+
+impl ffi::MessageDisplayer_methods for UwuDisplayer {
+    fn display_message(&self, msg: &CxxString) {
+        let uwu = uwu::uwu(msg.to_str().unwrap());
+        println!("{}", uwu);
+    }
+}
+
+// And here's a different pure virtual class.
+// Here's its definition from src/messages.h:
+// ```cpp
+// class MessageProducer {
+// public:
+//     virtual std::string get_message() const = 0;
+//     virtual ~MessageProducer() {};
+// };
+// ```
+// This one is notable only in that the interface of the C++ class
+// involves std::string, yet in Rust the subclass uses
+// std::unique_ptr<std::string> (for all the normal reasons in autocxx -
+// for now, at least, we can't hold non-trivial C++ objects on the Rust stack.)
+// All the boxing and unboxing is done automatically by autocxx layers.
+
+#[is_subclass(superclass("MessageProducer"))]
+#[derive(Default)]
+pub struct QuoteProducer;
+
+// Here we've chosen to have an explicit constructor instead rather than deriving
+// from CppSubclassDefault. It's functionally the same.
+impl QuoteProducer {
+    fn new() -> Rc<RefCell<Self>> {
+        Self::new_rust_owned(Self::default())
+    }
+}
+
+impl ffi::MessageProducer_methods for QuoteProducer {
+    fn get_message(&self) -> cxx::UniquePtr<CxxString> {
+        use ffi::ToCppString;
+        billy::SHAKESPEARE_QUOTES[fastrand::usize(0..billy::SHAKESPEARE_QUOTES.len())].into_cpp()
+    }
+}
+
+// Here's another subclass of the same 'displayer' class.
+// This one is more complex in two ways.
+//
+// First, we actually want to store some data here in our subclass.
+// That means we can't just allocate ourselves with Default::default().
+// And that means we need to be aware of the cpp_peer field which is
+// added by the #[subclass] macro.
+//
+// Second, we're going to simulate the observer/listener type pattern
+// in C++ where a const* is used to send messages around a codebase yet
+// recipients need to react by mutating themselves or otherwise actively
+// doing stuff. In C++ you'd probably need a const_cast. Here we use
+// interior mutability.
+
+#[is_subclass(superclass("MessageDisplayer"))]
+pub struct BoxDisplayer {
+    message_count: RefCell<usize>,
+}
+
+impl BoxDisplayer {
+    fn new() -> Rc<RefCell<Self>> {
+        Self::new_rust_owned(Self {
+            // As we're allocating this class ourselves instead of using [`Default`]
+            // we need to initialize the `cpp_peer` member ourselves. This member is
+            // inserted by the `#[is_subclass]` annotation. autocxx will
+            // later use this to store a pointer back to the C++ peer.
+            cpp_peer: Default::default(),
+            message_count: RefCell::new(1usize),
+        })
+    }
+}
+
+impl ffi::MessageDisplayer_methods for BoxDisplayer {
+    fn display_message(&self, msg: &CxxString) {
+        let msg = textwrap::fill(msg.to_str().unwrap(), 70);
+        let horz_line = std::iter::repeat("#").take(74).collect::<String>();
+        println!("{}", horz_line);
+        let msgmsg = format!("Message {}", self.message_count.borrow());
+        self.message_count.replace_with(|old| *old + 1usize);
+        println!("# {:^70} #", msgmsg);
+        println!("{}", horz_line);
+        for l in msg.lines() {
+            println!("# {:^70} #", l);
+        }
+        println!("{}", horz_line);
+    }
+}
+
+fn main() {
+    ffi::register_cpp_thingies();
+    // Construct a Rust-owned UwuDisplayer. We can also construct
+    // a C++-owned or self-owned subclass - see docs for `CppSubclass`.
+    let uwu = UwuDisplayer::default_rust_owned();
+    // The next line casts the &UwuDisplayerCpp to a &MessageDisplayer.
+    ffi::register_displayer(uwu.as_ref().borrow().as_ref());
+    // Constructs in just the same way as the first one, but using
+    // our explicit constructor.
+    let boxd = BoxDisplayer::new();
+    ffi::register_displayer(boxd.as_ref().borrow().as_ref());
+    let shakespeare = QuoteProducer::new();
+    ffi::register_producer(shakespeare.as_ref().borrow().as_ref());
+    ffi::run_demo();
+    ffi::run_demo();
+}
diff --git a/examples/subclass/src/messages.cc b/examples/subclass/src/messages.cc
new file mode 100644
index 0000000..4d24aab
--- /dev/null
+++ b/examples/subclass/src/messages.cc
@@ -0,0 +1,70 @@
+// 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.
+
+// This example shows Rust subclasses of C++ classes.
+// See messages.h and main.rs for most of the interesting code.
+
+#include "messages.h"
+#include <ctime>
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <functional>
+ 
+class CppExampleProducer : public MessageProducer {
+public:
+    CppExampleProducer() {}
+    std::string get_message() const {
+        std::time_t result = std::time(nullptr);
+        std::ostringstream st;
+        st << std::asctime(std::localtime(&result))
+           << result << " seconds since the Epoch";
+        return st.str();
+    }
+};
+
+class CppExampleDisplayer : public MessageDisplayer {
+public:
+    CppExampleDisplayer() {}
+    void display_message(const std::string& msg) const {
+        std::cout << "Message: " << msg << std::endl;
+    }
+};
+
+std::vector<std::reference_wrapper<const MessageProducer>> producers;
+std::vector<std::reference_wrapper<const MessageDisplayer>> displayers;
+CppExampleProducer cpp_producer;
+CppExampleDisplayer cpp_displayer;
+
+
+// Maybe we should use a language which tracks lifetimes
+// better than this. If only such a language existed.
+void register_displayer(const MessageDisplayer& displayer) {
+    displayers.push_back(displayer);
+}
+
+void register_producer(const MessageProducer& producer) {
+    producers.push_back(producer);
+}
+
+void register_cpp_thingies() {
+    register_producer(cpp_producer);
+    register_displayer(cpp_displayer);
+}
+
+void run_demo() {
+    for (auto& producer: producers) {
+        auto msg = producer.get().get_message();
+        for (auto& displayer: displayers) {
+            displayer.get().display_message(msg);
+            std::cout << std::endl;
+        }
+        std::cout << std::endl;
+    }
+}
+
diff --git a/examples/subclass/src/messages.h b/examples/subclass/src/messages.h
new file mode 100644
index 0000000..02ff248
--- /dev/null
+++ b/examples/subclass/src/messages.h
@@ -0,0 +1,33 @@
+// 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.
+
+// This example shows Rust subclasses of C++ classes.
+// Here are the C++ classes which we're subclassing.
+
+#pragma once
+
+#include <string>
+#include <memory>
+
+class MessageProducer {
+public:
+    virtual std::string get_message() const = 0;
+    virtual ~MessageProducer() {};
+};
+
+class MessageDisplayer {
+public:
+    virtual void display_message(const std::string& message) const = 0;
+    virtual ~MessageDisplayer() {};
+};
+
+void register_cpp_thingies();
+void register_producer(const MessageProducer& producer);
+void register_displayer(const MessageDisplayer& displayer);
+
+void run_demo();
diff --git a/examples/subclass/src/uwu.rs b/examples/subclass/src/uwu.rs
new file mode 100644
index 0000000..ce02510
--- /dev/null
+++ b/examples/subclass/src/uwu.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.
+
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub(crate) fn uwu(msg: &str) -> String {
+    uwuifier::uwuify_str_sse(msg)
+}
+
+#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
+pub(crate) fn uwu(_msg: &str) -> String {
+    "uwuification is unavailable for this pwatform :(".to_string()
+}