fn generate_unsafe_provider_probe_native_impl_trait() -> String {
    let mut decl= r#"
        /// See `UnsafeProviderProbeImpl` for additional details.  This subtrait provides an implementation of
        /// `UnsafeProviderProbeImpl` which wraps each of the Rust types into a `ProbeArgWrapper` and presents to the
        /// implementor of this trait the C representation of each probe argument.  It is presumbed that implmeentations of
        /// `UnsafeProviderProbeNativeImpl` are passing these parameters directly into C APIs.
        ///
        /// The implementor of this API for a specific tracing library need only implement all 13
        /// possible `fire` methods, one for each number of args from 0 to 12.
        ///
        /// *IMPORTANT NOTE TO IMPLEMENTORS*: Each of the `fireN` methods take arguments which may be either
        /// integers or possibly pointers to strings or other memory.  The caller guarantees that these are valid
        /// addresses *only* for the duration of the call.  Immediatley after the `fireN` method returns this memory may
        /// be freed.  Thus it's imperative that the probing implementation process probes synchronously.  Otherwise
        /// invalid memory accesses are inevitable.
        #[allow(clippy::too_many_arguments)]
        pub trait UnsafeProviderProbeNativeImpl
        {
            /// Tests if this probe is enabled or not.  This should be a very fast test, ideally just a memory
            /// access.  The Rust compiler should be able to inline this implementation for maxmimum performance.
            fn is_enabled(&self) -> bool;

            /// This is actually identical to `fire0` but is provided for consistency with the other arities
            unsafe fn c_fire0(&self);

    "#.to_string();

    for arity in 1..=MAX_ARITY {
        //For every possible arity level `N`, declare the probe method `c_fireN` which takes C native argument types
        let type_params = get_type_param_names(arity);

        decl += &format!(
            r##"
            unsafe fn c_fire{arg_count}<{type_list}>(&self, {args})
                where {where_clause};
            "##,
            arg_count = type_params.len(),
            type_list = type_params.join(","),
            args = xform_types_i(&type_params, |i, x| format!("arg{}: {}", i, x)).join(","),
            where_clause = xform_types(&type_params, |x| format!(
                "{t}: ProbeArgNativeType<{t}>",
                t = x
            ))
            .join(",")
        );
    }

    decl += "}\n";

    //Above was the declaration of UnsafeProviderProbeNativeImpl.  Now provide a blanket implementation of
    //UnsafeProviderProbeImpl for all implementations of UnsafeProviderProbeNativeImpl which performs the conversion
    //from Rust to C types using `ProbeArgWrapper`.
    decl += r#"
        impl<T: UnsafeProviderProbeNativeImpl> UnsafeProviderProbeImpl for T
        {
            fn is_enabled(&self) -> bool {
                T::is_enabled(self)
            }
            unsafe fn fire0(&self) { self.c_fire0() }

    "#;

    for arity in 1..=MAX_ARITY {
        //For every possible arity level `N`, implement the `fireN` method declared in the parent trait,
        //by wrapping each arg in its `ProbeArgWrapper` wrapper and passing a native C representation of that
        //arg to the `c_fireN` method.
        let type_params = get_type_param_names(arity);
        let wrapper_decls = xform_types_i(&type_params, |i, _| {
            format!("let wrapper{0} = wrap(arg{0})", i)
        })
        .join(";\n");
        let probe_args =
            xform_types_i(&type_params, |i, _| format!("wrapper{}.as_c_type()", i)).join(",");

        decl += &format!(
            r##"
            unsafe fn fire{arg_count}<{type_list}>(&self, {args})
                where {where_clause} {{
                {wrapper_decls};
                self.c_fire{arg_count}({probe_args});
            }}
            "##,
            type_list = type_params.join(","),
            arg_count = type_params.len(),
            args = xform_types_i(&type_params, |i, x| format!("arg{}: {}", i, x)).join(","),
            where_clause =
                xform_types(&type_params, |x| format!("{t}: ProbeArgType<{t}>", t = x)).join(","),
            wrapper_decls = wrapper_decls,
            probe_args = probe_args,
        );
    }

    decl += "}\n";

    decl
}
/// This generates the declaration of the `UnsafeProviderProbeNativeImpl` trait.  This trait provides an
/// implementation of `UnsafeProviderProbeImpl`, which invokes the wrapper code to convert all of the arguments
/// to their C native equivalent, and then passes that on to the specific implementator of `UnsafeProviderProbeNativeImpl`.
This generates the declaration of the `UnsafeProviderProbeNativeImpl` trait.  This trait provides an
implementation of `UnsafeProviderProbeImpl`, which invokes the wrapper code to convert all of the arguments
to their C native equivalent, and then passes that on to the specific implementator of `UnsafeProviderProbeNativeImpl`.
This generates the declaration of the ` UnsafeProviderProbeNativeImpl ` trait . This trait provides an implementation of ` UnsafeProviderProbeImpl ` which invokes the wrapper code to convert all of the arguments to their C native equivalent and then passes that on to the specific implementator of ` UnsafeProviderProbeNativeImpl ` .
fn generate_unsafe_provider_probe_native_impl_trait() -> String {
    let mut decl= r#"
        /// See `UnsafeProviderProbeImpl` for additional details.  This subtrait provides an implementation of
        /// `UnsafeProviderProbeImpl` which wraps each of the Rust types into a `ProbeArgWrapper` and presents to the
        /// implementor of this trait the C representation of each probe argument.  It is presumbed that implmeentations of
        /// `UnsafeProviderProbeNativeImpl` are passing these parameters directly into C APIs.
        ///
        /// The implementor of this API for a specific tracing library need only implement all 13
        /// possible `fire` methods, one for each number of args from 0 to 12.
        ///
        /// *IMPORTANT NOTE TO IMPLEMENTORS*: Each of the `fireN` methods take arguments which may be either
        /// integers or possibly pointers to strings or other memory.  The caller guarantees that these are valid
        /// addresses *only* for the duration of the call.  Immediatley after the `fireN` method returns this memory may
        /// be freed.  Thus it's imperative that the probing implementation process probes synchronously.  Otherwise
        /// invalid memory accesses are inevitable.
        #[allow(clippy::too_many_arguments)]
        pub trait UnsafeProviderProbeNativeImpl
        {
            /// Tests if this probe is enabled or not.  This should be a very fast test, ideally just a memory
            /// access.  The Rust compiler should be able to inline this implementation for maxmimum performance.
            fn is_enabled(&self) -> bool;
            /// This is actually identical to `fire0` but is provided for consistency with the other arities
            unsafe fn c_fire0(&self);
    "#.to_string();
    for arity in 1..=MAX_ARITY {
        //For every possible arity level `N`, declare the probe method `c_fireN` which takes C native argument types
        let type_params = get_type_param_names(arity);
        decl += &format!(
            r##"
            unsafe fn c_fire{arg_count}<{type_list}>(&self, {args})
                where {where_clause};
            "##,
            arg_count = type_params.len(),
            type_list = type_params.join(","),
            args = xform_types_i(&type_params, |i, x| format!("arg{}: {}", i, x)).join(","),
            where_clause = xform_types(&type_params, |x| format!(
                "{t}: ProbeArgNativeType<{t}>",
                t = x
            ))
            .join(",")
        );
    }
    decl += "}\n";
    //Above was the declaration of UnsafeProviderProbeNativeImpl.  Now provide a blanket implementation of
    //UnsafeProviderProbeImpl for all implementations of UnsafeProviderProbeNativeImpl which performs the conversion
    //from Rust to C types using `ProbeArgWrapper`.
    decl += r#"
        impl<T: UnsafeProviderProbeNativeImpl> UnsafeProviderProbeImpl for T
        {
            fn is_enabled(&self) -> bool {
                T::is_enabled(self)
            }
            unsafe fn fire0(&self) { self.c_fire0() }
    "#;
    for arity in 1..=MAX_ARITY {
        //For every possible arity level `N`, implement the `fireN` method declared in the parent trait,
        //by wrapping each arg in its `ProbeArgWrapper` wrapper and passing a native C representation of that
        //arg to the `c_fireN` method.
        let type_params = get_type_param_names(arity);
        let wrapper_decls = xform_types_i(&type_params, |i, _| {
            format!("let wrapper{0} = wrap(arg{0})", i)
        })
        .join(";\n");
        let probe_args =
            xform_types_i(&type_params, |i, _| format!("wrapper{}.as_c_type()", i)).join(",");
        decl += &format!(
            r##"
            unsafe fn fire{arg_count}<{type_list}>(&self, {args})
                where {where_clause} {{
                {wrapper_decls};
                self.c_fire{arg_count}({probe_args});
            }}
            "##,
            type_list = type_params.join(","),
            arg_count = type_params.len(),
            args = xform_types_i(&type_params, |i, x| format!("arg{}: {}", i, x)).join(","),
            where_clause =
                xform_types(&type_params, |x| format!("{t}: ProbeArgType<{t}>", t = x)).join(","),
            wrapper_decls = wrapper_decls,
            probe_args = probe_args,
        );
    }
    decl += "}\n";
    decl
}
fn generate_unsafe_provider_probe_native_impl_trait ( ) -> String { let mut decl = r#"
        /// See `UnsafeProviderProbeImpl` for additional details.  This subtrait provides an implementation of
        /// `UnsafeProviderProbeImpl` which wraps each of the Rust types into a `ProbeArgWrapper` and presents to the
        /// implementor of this trait the C representation of each probe argument.  It is presumbed that implmeentations of
        /// `UnsafeProviderProbeNativeImpl` are passing these parameters directly into C APIs.
        ///
        /// The implementor of this API for a specific tracing library need only implement all 13
        /// possible `fire` methods, one for each number of args from 0 to 12.
        ///
        /// *IMPORTANT NOTE TO IMPLEMENTORS*: Each of the `fireN` methods take arguments which may be either
        /// integers or possibly pointers to strings or other memory.  The caller guarantees that these are valid
        /// addresses *only* for the duration of the call.  Immediatley after the `fireN` method returns this memory may
        /// be freed.  Thus it's imperative that the probing implementation process probes synchronously.  Otherwise
        /// invalid memory accesses are inevitable.
        #[allow(clippy::too_many_arguments)]
        pub trait UnsafeProviderProbeNativeImpl
        {
            /// Tests if this probe is enabled or not.  This should be a very fast test, ideally just a memory
            /// access.  The Rust compiler should be able to inline this implementation for maxmimum performance.
            fn is_enabled(&self) -> bool;

            /// This is actually identical to `fire0` but is provided for consistency with the other arities
            unsafe fn c_fire0(&self);

    "# . to_string ( ) ; for arity in 1 ..= MAX_ARITY { //For every possible arity level `N`, declare the probe method `c_fireN` which takes C native argument types let type_params = get_type_param_names ( arity ) ; decl += & format ! ( r##"
            unsafe fn c_fire{arg_count}<{type_list}>(&self, {args})
                where {where_clause};
            "## arg_count type_params len ( ) type_list type_params join ( " " ) args xform_types_i ( type_params i x format ( " " i x ) ) join ( " " ) where_clause xform_types ( type_params x format ( " " t x ) ) join ( " " ) ) ; } decl += " \n " ; //Above was the declaration of UnsafeProviderProbeNativeImpl.  Now provide a blanket implementation of //UnsafeProviderProbeImpl for all implementations of UnsafeProviderProbeNativeImpl which performs the conversion //from Rust to C types using `ProbeArgWrapper`. decl += r#"
        impl<T: UnsafeProviderProbeNativeImpl> UnsafeProviderProbeImpl for T
        {
            fn is_enabled(&self) -> bool {
                T::is_enabled(self)
            }
            unsafe fn fire0(&self) { self.c_fire0() }

    "# ; for arity in 1 ..= MAX_ARITY { //For every possible arity level `N`, implement the `fireN` method declared in the parent trait, //by wrapping each arg in its `ProbeArgWrapper` wrapper and passing a native C representation of that //arg to the `c_fireN` method. let type_params = get_type_param_names ( arity ) ; let wrapper_decls = xform_types_i ( & type_params , | i , _ | { format ! ( " " i ) } ) . join ( " \n " ) ; let probe_args = xform_types_i ( & type_params , | i , _ | format ! ( " " i ) ) . join ( " " ) ; decl += & format ! ( r##"
            unsafe fn fire{arg_count}<{type_list}>(&self, {args})
                where {where_clause} {{
                {wrapper_decls};
                self.c_fire{arg_count}({probe_args});
            }}
            "## type_list type_params join ( " " ) arg_count type_params len ( ) args xform_types_i ( type_params i x format ( " " i x ) ) join ( " " ) where_clause xform_types ( type_params x format ( " " t x ) ) join ( " " ) wrapper_decls wrapper_decls probe_args probe_args ) ; } decl += " \n " ; decl }
This generates the declaration of the `UnsafeProviderProbeNativeImpl` trait.
This generates the declaration of the ` UnsafeProviderProbeNativeImpl ` trait .