I've a class which is a wrapper class(serves as a common interface) around another class implementing the functionality required. So my code looks like this.
template<typename ImplemenationClass> class WrapperClass {
// the code goes here
}
Now, how do I make sure that ImplementationClass can be derived from a set of classes only, similar to java's generics
<? extends BaseClass>
syntax?
It's verbose, but you can do it like this:
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_base_of.hpp>
struct base {};
template <typename ImplementationClass, class Enable = void>
class WrapperClass;
template <typename ImplementationClass>
class WrapperClass<ImplementationClass,
typename boost::enable_if<
boost::is_base_of<base,ImplementationClass> >::type>
{};
struct derived : base {};
struct not_derived {};
int main() {
WrapperClass<derived> x;
// Compile error here:
WrapperClass<not_derived> y;
}
This requires a compiler with good support for the standard (most recent compilers should be fine but old versions of Visual C++ won't be). For more information, see the Boost.Enable_If documentation.
As Ferruccio said, a simpler but less powerful implementation:
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_base_of.hpp>
struct base {};
template <typename ImplementationClass>
class WrapperClass
{
BOOST_STATIC_ASSERT((
boost::is_base_of<base, ImplementationClass>::value));
};
In the current state of things, there is no good way other than by comments or a third-party solution. Boost provides a concept check library for this, and I think gcc also has an implementation. Concepts are on the list of C++0x improvements, but I'm not sure if you can specify subtypes - they are more for "must support these operations" which is (roughly) equivalent.
Edit: Wikipedia has this section about concepts in C++0x, which is significantly easier to read than draft proposals.
See Stoustrup's own words on the subject.
Basically a small class, that you instantiate somewhere, e.g. the templated classes constructor.
template<class T, class B> struct Derived_from {
static void constraints(T* p) { B* pb = p; }
Derived_from() { void(*p)(T*) = constraints; }
};
Related
I need to access native C++ code .dll from Java application. native int function works well, but for Linkedlist Struct I cannot find any reference on the Internet how to declare the java interface
this C++ code
struct usb_relay_device_info
{
unsigned char *serial_number;
char *device_path;
usb_relay_device_type type;
usb_relay_device_info* next;
};
int EXPORT_API usb_relay_init(void);
struct usb_relay_device_info EXPORT_API * usb_relay_device_enumerate(void);
int EXPORT_API usb_relay_device_open(struct usb_relay_device_info* device_info);
This is the java part
public interface JNI extends Library {
JNI INSTANCE = (JNI) Native.loadLibrary("usb", JNI.class);
public static class usb_relay_device_info extends Structure {
public static class DeviceInfo extends usb_relay_device_info implements Structure.ByValue {
}
public byte[] serial_number = new byte[1024];
public String device_path;
public int type;
}
int usb_relay_init();
usb_relay_device_info.DeviceInfo usb_relay_device_enumerate();
int usb_relay_device_open(usb_relay_device_info.DeviceInfo deviceInfo);
}
I already created just the struct at the java code (NOT the Linkedlist Struct). So when I call the function the values are not showing up because it supposed to be a list (linkedlist in C++)
You say "I cannot find any reference on the Internet how to declare the java interface" but there are plenty of references, including JNA's Overview, linked to the main project page.
There you will find that char * is a C String and should be mapped to Java's String.
The usb_relay_device_type mapping has to be referenced in the API that you're mapping. In this case it is an enum type, which is an integer, so int is probably appropriate here. (There are cases where it can be a smaller integer value like short or byte but those are rare.)
As for the pointer to the next device, that is also referenced on the overview page under struct*. The link (or explicitly) links to Structure.ByReference. That may not be obvious, but the JNA FAQ, also linked on the main JNA project page, amplifies. If it's still not clear, here's a summary:
By default, Structures listed as fields inside a Structure are treated "By Value", that is, the full structure and its fields are inserted in line. To get this behavior you can simply declare the structure name.
If you want the opposite behavior (By Reference) then you must explicitly state that, and JNA will map a pointer to the structure elsewhere. This is the case you have, and the correct structure mapping is usb_relay_device_info.ByReference. (You'll also need to change the structure declaration to implement ByReference -- the JNA overview, linked above, has an example of this.)
When used in function arguments, such as usb_relay_device_open(), the opposite is true: the "By Reference" is the default, and you only need to explicity specify "By Value" if that's relevant. In this case, it's not -- the native declaration includes the pointer: (usb_relay_device_info*) so you want the ByReference behavior. You can just put usb_relay_device_info device_info there and the ByReference will be implicit. Or, if you prefer (it's not needed) you could do usb_relay_device_info.ByReference device_info and it would just be redundant.
So in summary your structure mapping should be:
class usb_relay_device_info extends Structure {
public static class ByReference extends usb_relay_device_info implements Structure.ByReference { }
public String serial_number;
public String device_path;
public int type;
public usb_relay_device_info.ByReference next;
};
You'll need to add the FieldOrder, preferably using an annotation.
I freely admit to being a little out of my depth here. My formal training in type systems is a good few decades behind me. I’ve used generics in Java rather trivially once or twice, but they’re not something about which I can claim to have a deep and thorough understanding. I’m also a relative newcomer to Scala, so I’m not claiming a deep or thorough understanding of its type system either.
I set out to update my XML Calabash v2 implementation, written in Scala (2.12 today) to use Saxon 9.9. Saxon 9.9 introduces generics in a number of places. Fine by me. I can cope, I imagine.
Except, I can’t apparently.
The stumbling block is trying to implement a class that extends the ExtensionFunctionDefinition class. It has an inner class that extends the ExtensionFunctionCall class. That, in turn, has an abstract method, call, defined thusly in Java:
public abstract Sequence<?> call(
XPathContext context,
Sequence[] arguments
)
My first attempt to define this in Scala was:
override def call(
context: XPathContext,
arguments: Array[Sequence]
): Sequence[_]
but that doesn’t compile: “trait Sequence takes type parameters”.
Which is true:
public interface Sequence<T extends Item<?>>
(Item, btw, is:
public interface Item<T extends Item<?>>
extends GroundedValue<T>
which I find slightly confusing for other reasons)
For my second attempt, I tried:
override def call(
context: XPathContext,
arguments: Array[Sequence[_]]
): Sequence[_]
But that, I’m told, doesn’t override anything. Hark, the compiler says:
[error] (Note that Array[net.sf.saxon.om.Sequence]
does not match Array[net.sf.saxon.om.Sequence[_]]:
their type parameters differ)
And here we seem to be at an impasse. I can just implement the damned thing in Java, of course, but is this an actual limitation in Scala or in my understanding?
I was lying before, by the way, about my first attempt. My first attempt was actually:
override def call(
context: XPathContext,
arguments: Array[Sequence[_ <: Item[_ <: Item[_]]]]
): Sequence[_ <: Item[_ <: Item[_]]]
which I crafted by bluntly copying Java into Scala and letting IntelliJ IDEA translate it. I had failed to work out what to do with the recursive nature of the Item declaration.
Try
override def call(context: XPathContext, arguments: Array[Sequence[_ <: Item[_]]]): Sequence[_] = ???
This here definitely compiles (and thereby confirms that Dmytro Mitin's proposal works):
// ExtensionFunctionCall.java
public interface ExtensionFunctionCall {
Sequence<?> call(String ctx, Sequence[] args);
}
// Item.java
public interface Item<T extends Item<?>> {}
// Sequence.java
public interface Sequence<T extends Item<?>> {}
// Impl.scala
class Impl extends ExtensionFunctionCall {
override def call(
ctx: String,
args: Array[Sequence[_ <: Item[_]]]
): Sequence[_] = ???
}
By the way, it's not just Scala's problem. If you forget Scala for a second, and try to implement it in Java, you get essentially the same errors:
class ImplJava implements ExtensionFunctionCall {
public Sequence<?> call(
String ctx,
Sequence<?>[] args
) {
return null;
}
}
gives:
ImplJava.java:1: error: ImplJava is not abstract and does not override abstract method call(String,Sequence[]) in ExtensionFunctionCall
class ImplJava implements ExtensionFunctionCall {
^
ImplJava.java:2: error: name clash: call(String,Sequence<?>[]) in ImplJava and call(String,Sequence[]) in ExtensionFunctionCall have the same erasure, yet neither overrides the other
public Sequence<?> call(
^
2 errors
Now, this is really mystifying, I have no idea how to write down this type in Java. I'm not sure whether it's even expressible in Java without reverting to 1.4-style. The Sequence[] thing is just evil, or, to quote this wonderful article linked by Dmytro Mitin:
Raw Types are bad. Stop using them
I think Sequence with no type parameters in java translates into Sequence[Foo] where Foo is the highest possible super-type (Item in this case).
So, I would expect something like this to work:
override def call(context: XPathContext, arguments: Array[Sequence[Item[_]]]): Sequence[_] = ???
I need to create some extension methods in my Java code. I've read some posts here in SO and people suggest XTend or Scala in order to achieve this.
Now, my question would be.. if i write kind of an Adapter layer in Scala (adding there my extension methods) and then using that project as a dependency for my own Java project, are those extended methods available for me to use, or they are defined just for the 'scope of Scala project' and then the JVM output cannot provide those new methods to the other project using it?
EDIT:
What i need to do is to extend a full hierarchy of classes in a given library and give some new functionality. As for Java's first approach I should extend every class in that hierarchy creating my own hierarchy of extended classes adding the new method there. I would like to avoid this and give the final user the sense of native functionality in the original hierarchy.
Regards.
As mentioned above in the comments, it is very close to C# but not exactly there because of the type erasure. For example, this works fine:
object myLibExtensions {
implicit class TypeXExtension( val obj: TypeX ) extends AnyRef {
def myCustomFunction( a: String ): String = {
obj.someMethod(a)
}
}
}
It will act somewhat similar to C# extension methods, i.e. create static method wrappers in reasonable cases (but not always).
The only thing I am missing in Scala is that you can't (or at least I couldn't figure out how to) return the values of the types being extended. For example, assume I want to have something like an extension method "withMeta" that works as follows:
class TypeY extends TypeX { def methodOfY(...) ...}
var y: TypeY = ....
y.withMeta(...).methodOfY(...)
The following didn't work for me:
object myLibExtensions {
private val something = ....
implicit class Extension[T<:TypeX]( val obj: T ) extends AnyRef {
def withMeta( meta: Meta[T] ): T = {
something.associateMeta(obj,meta)
val
}
}
}
... because T is being erased to TypeX. So effectively you will have to write extensions for all specific leaf classes of the hierarchy in this case, which is sad.
I have these methods declared in Java libraries:
Engine.java:
public <T extends EntitySystem> T getSystem(Class<T> systemType)
Entity.java:
public <T extends Component> T getComponent(Class<T> componentClass)
Now, I use these methods A LOT, and I would really like to use MyComponent::class (i.e. kotlin reflection) instead of the more verbose javaClass<MyComponent>() everywhere.
My EntitySystem and Component implementations are written in Kotlin.
So I thought I would create extension functions that take KClasses instead, but I am not quite sure how to make them work.
Something along the lines of...
public fun <C : Component> Entity.getComponent(type: KClass<out Component>): C {
return getComponent(type.javaClass)
}
But this does not work for several reasons: The compiler says type inference failed, since javaClass returns Class<KClass<C>>. And I need Class<C>. I also don't know how to make the method properly generic.
Can anyone help me create these methods?
In current Kotlin (1.0), the code would be simpler as:
public inline fun <reified C : Component> Entity.getComponent(): C {
return getComponent(C::class)
}
And can be called:
val comp: SomeComponent = entity.getComponent()
Where type inference will work, reify the generic type parameter (including any nested generic parameters) and call the method, which then uses the type parameter as a class reference.
You should use the extension property java instead of javaClass.
Additionally You can improve your API with reified type parameters and rewrite your code like:
public inline fun <reified C : Component> Entity.getComponent(): C {
return getComponent(C::class.java)
}
I have a C++ function:
struct Result {
//...
};
bool doSomething(Result[]);
If I use the following JNA binding, the function call works fine:
public class Result extends Structure {
//...
}
public interface CPPLibrary extends Library {
public static final CPPLibrary INSTANCE = (CPPLibrary)Native.loadLibrary("dllname");
boolean doSomething(Result[]);
}
But with direct call, I hit an IllegalArgumentException saying class [Lcom.usta.Result; is not a supported argument type (in method calcPV01 in class com.usta.CPPLibrary). My JNA code for the direct call-mapping:
public class CPPLibrary implements Library {
Native.register("dllname");
public static native boolean doSomething(Result[]);
}
I can see in com.sun.jna.Function#convertArgument() explicitly handles Structure[] but com.sun.jna.Native#getConversion(), which is used by direct call-mapping, does not handle Structure[].
The conversion is trivial, just call Structure.getPointer() on the first element of your structure array (assuming that you got the array from Structure.toArray in the first place).
You're actually better off with that when using direct mapping; when passing non-primitive, non-pointer types the JNI layer has to call back into the VM to derive the appropriate native data.
Feel free to file an issue for support of Structure[] arguments in direct mappings. That should be supported (JNA documentation notes that arrays of Pointer/String/WString/NativeMapped are not supported).
If I use a different method signature:
boolean doSomething(Pointer results);
it does work. But then I have to convert from Result[] to a Pointer my self.