-
Notifications
You must be signed in to change notification settings - Fork 334
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
C++ codegen for reporting arrow data type for structs (#2756)
* Part of #2647 * Next step after #2707 ### What Implements `to_arrow_data_type` (same exists in Rust) for all C++ components and datatypes. Started splitting up `cpp.rs` a tiny little bit, not gonna go the single file way `rust.rs` went there, too hard to handle now that there's more than one author on it. Test it yourself with `cargo codegen && ./examples/cpp/minimal/build_and_run.sh` Rough next steps: * implement same for unions * implement extension type decl (missing in this PR!), needed for instance to declare component types * serialize out data * testing (nothing in this PR is tested other than "it compiles!") * utilities for better usability ### Checklist * [x] I have read and agree to [Contributor Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and the [Code of Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md) * [x] I've included a screenshot or gif (if applicable) * [x] I have tested [demo.rerun.io](https://demo.rerun.io/pr/2756) (if applicable) - [PR Build Summary](https://build.rerun.io/pr/2756) - [Docs preview](https://rerun.io/preview/pr%3Aandreas%2Fcpp-arrow-datatype-definition-for-structs/docs) - [Examples preview](https://rerun.io/preview/pr%3Aandreas%2Fcpp-arrow-datatype-definition-for-structs/examples)
- Loading branch information
Showing
94 changed files
with
2,487 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# This is a sha256 hash for all direct and indirect dependencies of this crate's build script. | ||
# It can be safely removed at anytime to force the build script to run again. | ||
# Check out build.rs to see how it's computed. | ||
e11a5960ff29c75374e3298ae9f2728d9d6d838c517e1b1ee3bc2a18fada0efb | ||
e45f620a5a7e37189161bd67ebaa7b111fa0569a315fb28bd960dd0e564b1149 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
use std::collections::{BTreeMap, BTreeSet}; | ||
|
||
use proc_macro2::TokenStream; | ||
use quote::{format_ident, quote}; | ||
|
||
use super::NEWLINE_TOKEN; | ||
|
||
/// A C++ forward declaration. | ||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] | ||
#[allow(dead_code)] | ||
pub enum ForwardDecl { | ||
Struct(String), | ||
Class(String), | ||
} | ||
|
||
impl quote::ToTokens for ForwardDecl { | ||
fn to_tokens(&self, tokens: &mut TokenStream) { | ||
match self { | ||
ForwardDecl::Struct(name) => { | ||
let name_ident = format_ident!("{name}"); | ||
quote! { struct #name_ident; } | ||
} | ||
ForwardDecl::Class(name) => { | ||
let name_ident = format_ident!("{name}"); | ||
quote! { class #name_ident; } | ||
} | ||
} | ||
.to_tokens(tokens); | ||
} | ||
} | ||
|
||
/// Keeps track of necessary forward decls for a file. | ||
#[derive(Default)] | ||
pub struct ForwardDecls { | ||
/// E.g. `DataType` in `arrow` etc. | ||
declarations_per_namespace: BTreeMap<String, BTreeSet<ForwardDecl>>, | ||
} | ||
|
||
impl ForwardDecls { | ||
pub fn insert(&mut self, namespace: impl Into<String>, decl: ForwardDecl) { | ||
self.declarations_per_namespace | ||
.entry(namespace.into()) | ||
.or_default() | ||
.insert(decl); | ||
} | ||
} | ||
|
||
impl quote::ToTokens for ForwardDecls { | ||
fn to_tokens(&self, tokens: &mut TokenStream) { | ||
let Self { | ||
declarations_per_namespace, | ||
} = self; | ||
|
||
let declarations = declarations_per_namespace | ||
.iter() | ||
.map(|(namespace, declarations)| { | ||
let namespace_ident = format_ident!("{namespace}"); | ||
quote! { | ||
#NEWLINE_TOKEN | ||
namespace #namespace_ident { | ||
#(#declarations)* | ||
} | ||
} | ||
}); | ||
|
||
quote! { | ||
#NEWLINE_TOKEN | ||
#(#declarations)* | ||
#NEWLINE_TOKEN | ||
#NEWLINE_TOKEN | ||
} | ||
.to_tokens(tokens); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
use std::collections::BTreeSet; | ||
|
||
use proc_macro2::TokenStream; | ||
use quote::quote; | ||
|
||
use super::{NEWLINE_TOKEN, SYS_INCLUDE_PATH_PREFIX_TOKEN, SYS_INCLUDE_PATH_SUFFIX_TOKEN}; | ||
|
||
/// Keeps track of necessary includes for a file. | ||
#[derive(Default)] | ||
pub struct Includes { | ||
/// `#include <vector>` etc | ||
pub system: BTreeSet<String>, | ||
|
||
/// `#include datatypes.hpp"` etc | ||
pub local: BTreeSet<String>, | ||
} | ||
|
||
impl quote::ToTokens for Includes { | ||
fn to_tokens(&self, tokens: &mut TokenStream) { | ||
let Self { system, local } = self; | ||
|
||
let hash = quote! { # }; | ||
let system = system.iter().map(|name| { | ||
// Need to mark system includes with tokens since they are usually not idents (can contain slashes and dots) | ||
quote! { #hash include #SYS_INCLUDE_PATH_PREFIX_TOKEN #name #SYS_INCLUDE_PATH_SUFFIX_TOKEN #NEWLINE_TOKEN } | ||
}); | ||
let local = local.iter().map(|name| { | ||
quote! { #hash include #name #NEWLINE_TOKEN } | ||
}); | ||
|
||
quote! { | ||
#(#system)* | ||
#NEWLINE_TOKEN | ||
#(#local)* | ||
#NEWLINE_TOKEN | ||
#NEWLINE_TOKEN | ||
} | ||
.to_tokens(tokens); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
use proc_macro2::{Ident, TokenStream}; | ||
use quote::quote; | ||
|
||
use super::{doc_comment, NEWLINE_TOKEN}; | ||
|
||
#[derive(Default)] | ||
pub struct MethodDeclaration { | ||
pub is_static: bool, | ||
pub return_type: TokenStream, | ||
pub name_and_parameters: TokenStream, | ||
} | ||
|
||
impl MethodDeclaration { | ||
pub fn constructor(declaration: TokenStream) -> Self { | ||
Self { | ||
is_static: false, | ||
return_type: TokenStream::new(), | ||
name_and_parameters: declaration, | ||
} | ||
} | ||
|
||
pub fn to_hpp_tokens(&self) -> TokenStream { | ||
let Self { | ||
is_static, | ||
return_type, | ||
name_and_parameters, | ||
} = self; | ||
|
||
let modifiers = if *is_static { | ||
quote! { static } | ||
} else { | ||
quote! {} | ||
}; | ||
quote! { | ||
#modifiers #return_type #name_and_parameters | ||
} | ||
} | ||
|
||
pub fn to_cpp_tokens(&self, class_or_struct_name: &Ident) -> TokenStream { | ||
let Self { | ||
is_static: _, | ||
return_type, | ||
name_and_parameters, | ||
} = self; | ||
|
||
quote! { | ||
#return_type #class_or_struct_name::#name_and_parameters | ||
} | ||
} | ||
} | ||
|
||
/// A Cpp struct/class method. | ||
pub struct Method { | ||
pub doc_string: String, | ||
pub declaration: MethodDeclaration, | ||
pub definition_body: TokenStream, | ||
pub inline: bool, | ||
} | ||
|
||
impl Default for Method { | ||
fn default() -> Self { | ||
Self { | ||
doc_string: String::new(), | ||
declaration: MethodDeclaration::default(), | ||
definition_body: TokenStream::new(), | ||
inline: true, | ||
} | ||
} | ||
} | ||
|
||
impl Method { | ||
pub fn to_hpp_tokens(&self) -> TokenStream { | ||
let Self { | ||
doc_string, | ||
declaration, | ||
definition_body, | ||
inline: is_inline, | ||
} = self; | ||
|
||
let quoted_doc = if doc_string.is_empty() { | ||
quote! {} | ||
} else { | ||
doc_comment(doc_string) | ||
}; | ||
let declaration = declaration.to_hpp_tokens(); | ||
if *is_inline { | ||
quote! { | ||
#NEWLINE_TOKEN | ||
#quoted_doc | ||
#declaration { | ||
#definition_body | ||
} | ||
} | ||
} else { | ||
quote! { | ||
#NEWLINE_TOKEN | ||
#quoted_doc | ||
#declaration; | ||
} | ||
} | ||
} | ||
|
||
pub fn to_cpp_tokens(&self, class_or_struct_name: &Ident) -> TokenStream { | ||
let Self { | ||
doc_string: _, | ||
declaration, | ||
definition_body, | ||
inline, | ||
} = self; | ||
|
||
let declaration = declaration.to_cpp_tokens(class_or_struct_name); | ||
if *inline { | ||
quote! {} | ||
} else { | ||
quote! { | ||
#declaration { | ||
#definition_body | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.