Comparing underlying (derived) types pointed-to by std::unique_ptr - c++17

I am writing unit tests to exercise various code paths involving a factory class.
The factory returns a std::unique_ptr to a base type:
class Base {};
class Derived1 : public class Base {};
class Derived2 : public class Base {};
std::unique_ptr<Base> Type::Factory(enum rtype) const {
switch(rtype) {
case d1: return std::make_unique<Derived1>();
case d2: return std::make_unique<Derived2>();
default: return std::make_unique<Derived1>();
}
}
So in the test I want to ensure that the correct type is returned (factories are breeding ground for cut'n'paste bugs).
Is there a way of checking what type is returned?
This: EXPECT_TRUE(typeid(Derived1), typeid(type.get()); is false because the type.get() is that of Base and not the rtype that was passed in.

This: EXPECT_TRUE(typeid(Derived1), typeid(type.get()); is false because the type.get() is that of Base and not the rtype that was passed in.
typeid( type.get() ) will get the typeid of the base pointer, i.e. the type that get() is declared as returning. To get the real dynamic type of the pointed-to object, whatever that may be, you should dereference the pointer:
typeid( *type.get() )

You need to use RTTI. The type is erased to Base when used.
You can do a dynamic cast to get the proper type, something like:
EXPECT_FALSE(dynamic_cast<Derived1*>(type.get()) == nullptr)
If dynamic_cast fails (type is not of Derived1) dynamic_cast will return a nullptr.

Related

Create nullable object based on nullable value

i have to create a domain class object which has a nullable attribute. This Creating is in an extansion of a primitive class.
For example: Domainclass
Meeting({required String id, required Datetime date, Example? example})
behind Example is an class like so: Example(String value)
MeetingPrimitive.dart:
extension MeetingPrimitiveX on Meeting {
Meeting toDomain() {
return Meeting(
id: id,
date: date,
example: example == null ? null : Example(example)
}
}
My question is, how can i simplify this:
example == null ? null : Example(example)
'''
thanks in advance
You generally can't.
You can change it in various ways, but nothing is more direct than what you have here.
One variant would be:
extension DoWith<T> on T {
R doWith<R>(R Function(T) action) => action(this);
}
With that, you can write:
example?.doWith(Example.new)
to conditionally call the Example.new constructor (tear-off of the unnamed constructor) if example is non-null.
Slightly shorter, requires a helper function, and ... isn't actually more readable IMO.

TypeError while attempting to sort a list of custom objects

I'm new to Dart and tried to get a class to implement List using the answers here, and tried to sort a list of these objects using the docs here. I deleted most of my code in an effort to post a MWE:
import 'dart:collection';
class Transaction<E> extends ListBase<E>{
DateTime when;
Transaction(this.when);
List innerList = new List();
int get length => innerList.length;
void set length(int length){
innerList.length = length;
}
void operator[]=(int index, E value){
innerList[index] = value;
}
E operator [](int index) => innerList[index];
void add(E value) => innerList.add(value);
void addAll(Iterable<E> all) => innerList.addAll(all);
}
class Forecaster{
var transactions;
Forecaster(){
this.transactions = new List<dynamic>();
}
void tabulate(){
transactions.sort((a,b) => a.when.compareTo(b.when)); //problem line?
for(var d in transactions){
d.asMap().forEach((index,content){
int len = content.toStringAsFixed(2).length;
});
}
}
void forecast(var forWhen){
var first = new Transaction(DateTime.now());
first.addAll([5,9]);
transactions.add(first);
}
}
void main(){
Forecaster myTest = new Forecaster();
var dub = myTest;
dub..forecast(DateTime.now())
..tabulate();
}
Running with the problem line results in an exception (Uncaught exception: TypeError: Closure 'Forecaster_tabulate_closure': type '(dynamic, dynamic) => dynamic' is not a subtype of type '(dynamic, dynamic) => int') I don't understand. If I comment out the problem line, the TypeError goes away. Is the TypeError because I did something wrong when defining Transaction? I'm attempting this with DartPad.
I'm new to Dart too, so my explanation might not be 100% on the money, but I believe, yes, the main issue is the type assignment of transactions. I think because you initialize it as a var, it is having trouble deducing the type of a.when, which is means it also doesn't know the type of a.when.compareTo(), and assumes dynamic. You are feeding the output of compareTo into List.sort() which is expecting an int from the anonymous function. Thus the error that it wanted an int but got dynamic.
The easiest way to address this is to initialize transactions with a more explicit type rather than as var:
List<Transaction> transactions;
Forecaster(){
this.transactions = new List<Transaction>();
}
Also, to confirm that it is an issue with it not being able to infer the return type of compareTo, I tried leaving your code as-is, but explicitly casting the result as int, and that also worked:
transactions.sort((a,b){
return (a.when.compareTo(b.when) as int);
});
Note: code like the above and using lots of dynamics and vars is in general not great practice with Dart - you lose a lot of the benefits of having a typed language. You might also notice that when you type in an IDE, you don't get methods auto-suggested when you do stuff like this - for example, until I changed transactions to an explicit type of list, typing a.when did not trigger autocomplete, and my IDE thought the type was dynamic, not DateTime.
Your problem is with the types. The code:
var transactions;
Forecaster(){
this.transactions = new List<dynamic>();
}
void tabulate(){
transactions.sort((a,b) => a.when.compareTo(b.when));
first declares transactions to have type dynamic.
Then you call sort on that with an argument which is inferred to have type dynamic Function(dynamic, dynamic) (because there is no clue available to say otherwise in the type of transactions).
However, the actual run-time type of transactions is List<Transaction>, and that requires a function argument of type int Function(Transaction, Transaction). The type dynamic Function(dynamic, dynamic) is not a sub-type of int Function(Transaction, Transaction) (the return type has to be a subtype of int for that to be the case) so you get a run-time error.
If you change transactions to have type List<Transaction>, then the type inference will have a clue when it gets to the function literal. It will infer that (a, b) => a.when.compareTo(b.when) in a context expecting int Function(Transaction, Transaction) will have that type.
Even if you just change transactions to List<dynamic>, it will still work, it will just make a.when.compareTo(b.when) be dynamic invocations.

clang-AST traversal - How to get member variables of a class

I want to traverse the AST of a simple class having one member variable and one method. I have figured out that the class is represented as CXXRecordDecl.
What is the api within CXXREcordDecl to get the list of member variables which are represented as FieldDecl ?
The fields can be retrieved with RecordDecl::fields (there exist also methods the get the begin and end iterators of that range), e.g. for a CXXRecordDecl
CXXRecordDecl* cl = ...;
for (const auto& field : cl->fields) {
const auto& name = field->getName();
const auto field_cl = field->getType()->getAsCXXRecordDecl();
}
Similarly you would access the methods with methods().

Swift nested class properties

Does swift not have nested classes??
For example, I can't seem to access the property test of the master class from the nested class.
class master{
var test = 2;
class nested{
init(){
let example = test; //this doesn't work
}
}
}
Swift's nested classes are not like Java's nested classes. Well, they're like one kind of Java's nested classes, but not the kind you're thinking of.
In Java, an instance of an inner class automatically has a reference to an instance of the outer class (unless the inner class is declared static). You can only create an instance of the inner class if you have an instance of the outer class. That's why in Java you say something like this.new nested().
In Swift, an instance of an inner class is independent of any instance of the outer class. It is as if all inner classes in Swift are declared using Java's static. If you want the instance of the inner class to have a reference to an instance of the outer class, you must make it explicit:
class Master {
var test = 2;
class Nested{
init(master: Master) {
let example = master.test;
}
}
func f() {
// Nested is in scope in the body of Master, so this works:
let n = Nested(master: self)
}
}
var m = Master()
// Outside Master, you must qualify the name of the inner class:
var n = Master.Nested(master:m)
// This doesn't work because Nested isn't an instance property or function:
var n2 = m.Nested()
// This doesn't work because Nested isn't in scope here:
var n3 = Nested(master: m)
This solution is sort of similar to how I use it in C#, and I have successfully tested it in Xcode.
Here's a breakdown of the process:
Your nested class needs to be made optional so you don't have to initialize it, so theres a '?' in the declaration; if you initialize both your parent class and your nested class, you end up with a 'recursion' effect and an error is generated
Create a regular function that receives an argument of the same type as your main class
Pass that argument to your nested class (this can go into the nested object's normal initializer). - Since objects are passed by reference by default, there's nothing special to get your nested class to link to the parent class
Inside your nested class, you need a variable of the same type as your parent class
From here on out set up everything as you normally would.
In the code execution area, your nested class object also needs to be regarded as optional (hence the '?'). If you forget about it, Xcode will add it anyways.
In this example, I wanted to design a keyword "set," so when I set variables, I can type:
testClass.set.(and then a descriptive method name)
Here is the code, and its goal is to output "test" in the console, after the value is set via the nested object:
class testClass
{
var test_string:String = ""
var set: class_set?
func construct_objects(argument: testClass)
{
self.set = class_set(argument: argument)
}
class class_set
{
var parent:testClass
init(argument: testClass)
{
parent = argument
}
func test_string_to_argument(argument: String)
{
parent.test_string = argument
}
}
}
var oTestClass = testClass()
oTestClass.construct_objects(oTestClass)
oTestClass.set?.test_string_to_argument("test")
print(oTestClass.test_string)
Nested for Swift and Java
Swift has Nested Types definitions
Java has more complex hierarchy of nested class
Swift's Nested is more similar to Java's Static Nested, as a result you do not have an access to properties of outer class. To get access of outer class you can pass it as a parameter.

what type does my object query return?

Public Function List_category() As Myobj
Dim query = From subcat In _dataContext.subcategories, _
cat In _dataContext.categories _
Where subcat.CategoryID = cat.CategoryID _
Select New Myobj() With { _
.SubcatId = subcat.SubCategoryID, _
.SubcatName = subcat.SubCategoryName, _
.CatId = cat.CategoryID, _
.CatName = cat.CategoryName _
}
return ?????????
End Function
Public Class Myobj
Private m_SubcatId As Integer
Private m_SubcatName As String
Private m_catId As Integer
Private m_catName As String
Public Property SubcatId() As Integer
Get
Return m_SubcatId
End Get
Private Set(ByVal value As Integer)
m_SubcatId = value
End Set
End Property
Public Property SubcatName() As String
Get
Return m_SubcatName
End Get
Private Set(ByVal value As String)
m_SubcatName = value
End Set
End Property
Public Property CatId() As Integer
Get
Return m_catId
End Get
Private Set(ByVal value As Integer)
m_catId = value
End Set
End Property
Public Property CatName() As String
Get
Return m_catName
End Get
Private Set(ByVal value As String)
m_catName = value
End Set
End Property
End Class
doesnt works!!!!
It Says 'Set' accessor of property 'SubcatName' is not accessible.
You can create a custom type and modify your select to instantiate that for the return. Take a look here: Linq To Sql return from function as IQueryable<T>
Compiler is just telling you that you have declared Private Set on SubcatName and yet ypou are trying to assing a value to it after New Myobj().
For a first run you can declare a POD class (plain old data - just public data, no methods or properties) and once you see it runnung you can go tweaking it, adding methods etc.
If it's really important that all properties are read-only you'll need to try making your querying method a static member of the same class.
Also, there is a way to return anonymous type and cast it back to equivalent anonymous type declared at the receiving side. Got to move on to C# though :-)
Example (read article):
// Method that returns anonymous type as object
object ReturnAnonymous()
{
return new { City="Prague", Name="Tomas" };
}
// Application entry-point
void Main()
{
// Get instance of anonymous type with 'City' and 'Name' properties
object o = ReturnAnonymous();
// This call to 'Cast' method converts first parameter (object) to the
// same type as the type of second parameter - which is in this case
// anonymous type with 'City' and 'Name' properties
var typed = Cast(o, new { City="", Name="" });
Console.WriteLine("Name={0}, City={1}", typed.Name, typed.City);
}
// Cast method - thanks to type inference when calling methods it
// is possible to cast object to type without knowing the type name
T Cast<T>(object obj, T type)
{
return (T)obj;
}

Resources