about CppWinRT internal 2 - c++-winrt

We know that the implementation class does not inherit from winrt::Windows::Foundation::IUnknow, for example
struct App : ApplicationT<App>
{...}
App does not have the as and try_as member functions, so how does the following code work?
// base.h (v2.0.190620.2 line 509)
template <typename D, typename I>
struct require_one : consume_t<D, I>
{
operator I() const noexcept
{
return static_cast<D const*>(this)->template try_as<I>(); // A
}
};
for the code at A, D is in fact App, it should not work. Please help, many thanks!!!

Related

Limit allowed COM Interfaces by using template function with limited variadic parameters (std::is_same)

I have wrapper classes contaning COM pointers (or smart pointers) to different interfaces.
INTEND:
Some COM classes can be obtained from various other COM interfaces, and I want to make a template constructor with variadic types, which would allow passing arguments only of appropriate types.
something like:
template <class T, class = typename
std::enable_if<std::is_base_of<IUnknown, T>::value>::type, class ... Types>
class WithCOMptrbase
{
protected:
T* ptr_;
public:
//construct smart pointer by copy
WithCOMptrbase(T* ptr, bool AddRef = false)
: ptr_(ptr)
{
if (AddRef) ptr_->AddRef();
}
/*construct a smart pointer by querying an interface from an argument of
a type which is the same as one of the variadics*/
template <class TypeOther, class = typename
std::enable_if<syd::is_same<Types... , TypeOther>::value... ||
...>::type> /*there needs to be a proper version*/
WithCOMptrbase(TypeOther* ptr)
: ptr_(cQueryInterface<T>(ptr))
{}
//other methods
};
helper function:
template <class U, class = typename
std::enable_if<std::is_base_of<IUnknown, U>::value>::type>
T* cQueryInterface<T>(U *ptr)
{
T* out;
HRESULT hr = ptr->QueryInterface(__uuidof(T), (void**)&out);
if (!SUCCEEED(hr)) throw _com_error(hr);
return out;
}
Therefore, I will define my wrapper class
class WrapperClass : protected WithCOMptrbase<IThis, IInterface1, IInterface2, IInterface3>
{
//methods
};
So far I have found this thread:
How to make a variadic is_same?
but it is only about structs, not functions.
My goal is to limit the possibility of passing inapproprtiate Interface pointer, hence not to deal with wrong interface errors at runtime.
UPDATE:
Since Composition is preferable over inheritance, I've done some rethinking and decided to use a template function rather than a template class. So far I've managed to combine given answers and came up with this:
template <bool S, class Out, class Other, typename
std::enable_if<S>::type* = nullptr>
//copy-construct Smart Pointer for same Interfaces
WComPtr<Out> WFilterSame(const WComPtr<Other>& pOther)
{
return WComPtr<Out>(pOther);
}
template <bool S, class Out, class Other, typename
std::enable_if<!S>::type* = nullptr>
//Query Interface if differ
WComPtr<Out> WFilterSame(const WComPtr<Other>& pOther)
{
return pOther.QueryInterface<Out>();
}
template <class Out, class ... Permitted, class Other>
WComPtr<Out> WFilterComInterfPtr(const WComPtr<Other>& pOther)
{
static_assert(std::is_same<Out, Other>::value ||
(std::is_same<Permitted, Other>::value || ...),
"Interface is not supported.");
return WFilterSame<std::is_same<Out, Other>::value, Out>(pOther);
}
Now I can define a constructor of my COM wrapper class:
class WComClass
{
private:
WComPtr<Interface> pComPtr_; //My Smart COM pointer
template <class Other>
WComPtr<Interface> WFilter(const WComPtr<Other>& pOther)
{
return WFilterComInterfPtr<Interface, IAllowed1, IAllowed2>(pOther);
}
public:
template <class Other>
WComClass(const WComPtr<Other>& pOther)
: pComPtr_(WFilter(pOther))
{}
//methods
};
So far it behaved as intended (WFilterComInterfPtr), I don't expect it to fail in the wrapper class costructor.
Try with
template <class TypeOther, class =
std::enable_if_t<(std::is_same_v<Types, TypeOther> || ...)>>
WithCOMptrbase(TypeOther* ptr)
: ptr_(cQueryInterface<T>(ptr))
{}
I mean... you're using three ellipsis instead of one (remove the ellipsis after ::value and the one after Types) and you need an additional couple of parentheses.
Off topic: are you sure that works
template <class T, class ... Types, class = typename
std::enable_if<std::is_base_of<IUnknown, T>::value>::type>
class WithCOMptrbase
?
SFINAE through a default type after a variadic list?
How about CRTP to avoid some template:
template <typename Base, typename T>
class Impl
{
public:
Impl() = default;
explicit Impl(T*) { static_cast<Base*>(this)->ptr_ = cQueryInterface<T>(ptr); }
};
template <class T, class ... Ts>
class WithCOMptrbase : private Impl<WithCOMptrbase<T, Ts...>, Ts>...
{
static_assert(std::is_base_of<IUnknown, T>::value);
static_assert((std::is_base_of<IUnknown, Ts>::value && ...));
template <typename, typename> friend struct Impl; // We don't have variadic friend :/
protected:
T* ptr_ = nullptr;
public:
using Impl<WithCOMptrbase, Ts>::Impl...;
//construct smart pointer by copy
explicit WithCOMptrbase(T* ptr, bool AddRef = false) : ptr_(ptr)
{
if (AddRef) ptr_->AddRef();
}
//other methods
};

How to reference a member of a module in its parent scope, from a module?

This simple example works in main.rs
pub mod types {
pub struct Foo {
_var: usize,
}
}
use types::Foo;
fn main() {
let _unused: Foo;
println!("Hello, world!");
}
However, when its compiled in a file which is its self a module, this gives an error:
error: unresolved import `types::Foo`. Maybe a missing `extern crate types`?
Is it possible to make a reference to a submodule's public member, from a module?
When in a module, self needs to be used, eg:
pub mod types {
pub struct Foo {
_var: usize,
}
}
use self::types::Foo; // <-- self here
Thanks to #nox on IRC for this answer.

How to reference private types from public functions in private modules?

I want to group similar functions in a file. Those functions need to return a type which is not public:
struct MyStruct;
mod my_mod {
use super::MyStruct;
// There are other, similar functions that also return `MyStruct`
pub fn foo() -> MyStruct {
MyStruct
}
}
fn main() {
let _var = my_mod::foo();
}
This fails with the error
error[E0446]: private type `MyStruct` in public interface
--> src/main.rs:7:3
|
1 | struct MyStruct;
| - `MyStruct` declared as private
...
7 | pub fn foo() -> MyStruct { MyStruct }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
In general, it makes sense not to allow public functions to have private types in their signature, but in this specific case the structure is available at the modules root level.
Is there a way to support this without making MyStruct public?
I have a feeling that this error is unwarranted. It should only be an error if my_mod is pub or if the functions are re-exported in an outer scope.
That said, I found a workaround: move MyStruct to a sibling module and make MyStruct pub, but not the module.
use types::MyStruct;
mod types {
pub struct MyStruct;
}
mod my_mod {
use super::MyStruct;
pub fn foo() -> MyStruct {
MyStruct
}
}
fn main() {
let _var = my_mod::foo();
}
I encountered this same problem. Rust 2018 seems to have solved it; just refer to the submodule's "public" function as pub(crate), AKA pub(crate) fn foo().
This makes the function only public to the crate: https://doc.rust-lang.org/nightly/edition-guide/rust-2018/module-system/more-visibility-modifiers.html

how to deal with embedded interfaces and share data between them

I would like to better understand how to use interfaces, mainly to split code in reusable components and at the same time make it more easy for testing, currently my main question is how to share/get data between the interfaces that belong to a main interface, for example:
https://play.golang.org/p/67CQor1_pY
package main
import (
"fmt"
)
type MainInterface interface {
SubInterfaceA
SubInterfaceB
}
type SubInterfaceA interface {
MethodA()
GetterA(s implementMain)
}
type SubInterfaceB interface {
MethodB()
GetterB(s implementMain)
}
type implementA struct{}
func (ia *implementA) MethodA() { fmt.Println("I am method A") }
func (ia *implementA) GetterA(s implementMain) {
fmt.Println(s.Data)
}
type implementB struct{}
func (ib *implementB) MethodB() { fmt.Println("I am method B") }
func (ib *implementB) GetterB(s implementMain) {
fmt.Println(s.Data)
}
type implementMain struct {
Data string
SubInterfaceA
SubInterfaceB
}
func New(d string) implementMain {
return implementMain{
Data: d,
SubInterfaceA: &implementA{},
SubInterfaceB: &implementB{},
}
}
func main() {
var m MainInterface
m = New("something")
fmt.Println(m.(implementMain).Data)
m.MethodA() // prints I am method A
m.MethodB() // prints I am method B
m.GetterA(m.(implementMain)) // prints "something"
m.GetterB(m.(implementMain)) // prints "something"
}
In the above code, within the methods of struct implementA or implementB how to access the struct elements of the parent holder implementMain that implements MainInterface without passing it as an argument?
with holder struct I mean:
type implementMain struct {
Data string
SubInterfaceA
SubInterfaceB
}
If I am right SubInterfaceA and SubInterfaceB are embedded and help to make the struct implementMain satisfy the MainInterface:
type MainInterface interface {
SubInterfaceA
SubInterfaceB
}
But within the embedded methods of the SubInterfaceA or subInterfaceB what is the best practice to use in order to be available to get the data string?
I created Getter(s implementMain) method and passed the holder struct, but had to cast type:
m.GetterA(m.(implementMain))
I don't know if by satisfying a interface, all the involved interfaces can become part of the same structure scope and if they do, how to get/share data between them or either between its components?, for example besides been available to reach data string how from SubInterfaceA get/access SubInterfaceB

Objective-C enum not recognized in Swift

I have a delegate method that passes an enum as an argument:
func gestureRecognizer(gestureRecognizer: JTTableViewGestureRecognizer!, commitEditingState state: JTTableViewCellEditingState, forRowAtIndexPath indexPath: NSIndexPath!) -> Void {
//....
}
The enum is JTTableViewCellEditingState. It's implementation is in the same header file as the delegate method. It's as follows:
typedef enum {
JTTableViewCellEditingStateMiddle,
JTTableViewCellEditingStateLeft,
JTTableViewCellEditingStateRight,
} JTTableViewCellEditingState;
Yet trying to reference a state, for example Left, gives an error:
if state == JTTableViewCellEditingState.Left {
'JTTableViewCellEditingState.Type' does not have a member named 'Left'
Trying to do it the old, Objective-C way, like some kind of peasant, gives me a different, more expected, error:
if state == JTTableViewCellEditingStateLeft {
Cannot invoke '==' with an argument list of type '(JTTableViewCellEditingState, JTTableViewCellEditingState)'
I'm wondering how I should overcome this issue? I believe referencing Objective-C enums has worked just fine in the past.
This type of enum decleration causes problems in swift. I had similar problem. My solution is to create a helper objective-c method that does comparison and use that method in swift whenever == is needed.
Other solution may be refactor that code if you can and convert it proper enum decleration in objective-c.
typedef NS_ENUM(NSInteger, MyEnum) {
MyEnumValue1,
MyEnumValue2
};
Can you use NS_ENUM instead? And then try JTTableViewCellEditingState.JTTableViewCellEditingStateLeft or even .JTTableViewCellEditingStateLeft to access your enum. If you can't change it to NS_ENUM, please have a look at Using non NS_ENUM objective-C enum in swift
In my environment - Xcode Version 6.1.1 (6A2006):
typedef enum {
JTTableViewCellEditingStateMiddle,
JTTableViewCellEditingStateLeft,
JTTableViewCellEditingStateRight,
} JTTableViewCellEditingState;
is exported to Swift as:
struct JTTableViewCellEditingState {
init(_ value: UInt32)
var value: UInt32
}
var JTTableViewCellEditingStateMiddle: JTTableViewCellEditingState { get }
var JTTableViewCellEditingStateLeft: JTTableViewCellEditingState { get }
var JTTableViewCellEditingStateRight: JTTableViewCellEditingState { get }
So, this should works:
func gestureRecognizer(gestureRecognizer: JTTableViewGestureRecognizer!, commitEditingState state: JTTableViewCellEditingState, forRowAtIndexPath indexPath: NSIndexPath!) -> Void {
if state.value == JTTableViewCellEditingStateLeft.value {
// ...
}
}