Why is the struct unknown at compiletime in the code? - struct

I was wondering how I could change the code below such the bmBc is computed at compile time . The one below works for runtime but it is not ideal since I need to know the bmBc table at compile-time . I could appreciate advice on how I could improve on this.
import std.conv:to;
import std.stdio;
int [string] bmBc;
immutable string pattern = "GCAGAGAG";
const int size = to!int(pattern.length);
struct king {
void calculatebmBc(int i)()
{
static if ( i < size -1 )
bmBc[to!string(pattern[i])]=to!int(size-i-1);
// bmBc[pattern[i]] ~= i-1;
calculatebmBc!(i+1)();
}
void calculatebmBc(int i: size-1)() {
}
}
void main(){
king myKing;
const int start = 0;
myKing.calculatebmBc!(start)();
//1. enum bmBcTable = bmBc;
}

The variables bmBc and bmh can't be read at compile time because you define them as regular runtime variables.
You need to define them as enums, or possibly immutable, to read them at compile time, but that also means that you cannot modify them after initialization. You need to refactor your code to return values instead of using out parameters.
Alternatively, you can initialize them at runtime inside of a module constructor.

Related

std::list<int> predicate call to function: Error C3867 function call missing argument list

I am using std::list's predicate to update the list based on predicate. But calling in the OnInitDialog() throws compilation error. My code is as follows:
The below is .h:
class CDlgWindow : public CDialog
{
private:
bool single_digit (const int &value);
int _days;
}
The below is .cpp:
CDlgWindow::CDlgWindow(CWnd* pParent, CString strInfo, int days) //ctor
{
_days = days;
//_strInfo = strInfo
}
bool CDlgWindow::single_digit(const int& value)
{
return (value >= _days);
}
BOOL CDlgWindow::OnInitDialog()
{
CDialog::OnInitDialog();
CenterWindow();
.
.
.
int numArr[] = {10,20,30,40};
int size = sizeof(numArr)/sizeof(numArr[0]);
std::list<int> numList (numArr, numArr+size);
numList.remove_if(single_digit); //Error C3867 here!
.
.
}
Complete error message:
Error C3867 function call missing argument list, use '&CDlgWindow::single_digit' to create a pointer to member.
I am trying to understand the functors concept. As I checked in C++11, we have lambdas for easier implementation. Please guide me to understand more on this issue. Thanks!
std::list's remove_if member needs a unary predicate (p) that operates on values (v). The expression p(v) must be valid. Which it isn't if p is a non-static class member (see repro).
There are two options:
Make the predicate (single_digit) a static class member:
class CDlgWindow : public CDialog
{
private:
static bool single_digit (const int &value);
// ...
}
Make the predicate a free function:
bool single_digit(int const& value) {
static int days_ = ...;
return (value >= days_);
}
If you go with option 1 you will have to make _days static as well, since a static member function cannot access non-static instance data. If _days is a compile-time constant, make sure to mark it const as well. That'll open up some compiler optimizations.
This is all hoping that things haven't significantly changed between C++98 and C++11. It's hard to find a C++98 compiler to verify this.

Is it possible in Mono.Cecil to determine the actual type of an object on which a method is called?

For example, consider the following C# code:
interface IBase { void f(int); }
interface IDerived : IBase { /* inherits f from IBase */ }
...
void SomeFunction()
{
IDerived o = ...;
o.f(5);
}
I know how to get a MethodDefinition object corresponding to SomeFunction.
I can then loop through MethodDefinition.Instructions:
var methodDef = GetMethodDefinitionOfSomeFunction();
foreach (var instruction in methodDef.Body.Instructions)
{
switch (instruction.Operand)
{
case MethodReference mr:
...
break;
}
yield return memberRef;
}
And this way I can find out that the method SomeFunction calls the function IBase.f
Now I would like to know the declared type of the object on which the function f is called, i.e. the declared type of o.
Inspecting mr.DeclaringType does not help, because it returns IBase.
This is what I have so far:
TypeReference typeRef = null;
if (instruction.OpCode == OpCodes.Callvirt)
{
// Identify the type of the object on which the call is being made.
var objInstruction = instruction;
if (instruction.Previous.OpCode == OpCodes.Tail)
{
objInstruction = instruction.Previous;
}
for (int i = mr.Parameters.Count; i >= 0; --i)
{
objInstruction = objInstruction.Previous;
}
if (objInstruction.OpCode == OpCodes.Ldloc_0 ||
objInstruction.OpCode == OpCodes.Ldloc_1 ||
objInstruction.OpCode == OpCodes.Ldloc_2 ||
objInstruction.OpCode == OpCodes.Ldloc_3)
{
var localIndex = objInstruction.OpCode.Op2 - OpCodes.Ldloc_0.Op2;
typeRef = locals[localIndex].VariableType;
}
else
{
switch (objInstruction.Operand)
{
case FieldDefinition fd:
typeRef = fd.DeclaringType;
break;
case VariableDefinition vd:
typeRef = vd.VariableType;
break;
}
}
}
where locals is methodDef.Body.Variables
But this is, of course, not enough, because the arguments to a function can be calls to other functions, like in f(g("hello")). It looks like the case above where I inspect previous instructions must repeat the actions of the virtual machine when it actually executes the code. I do not execute it, of course, but I need to recognize function calls and replace them and their arguments with their respective returns (even if placeholders). It looks like a major pain.
Is there a simpler way? Maybe there is something built-in already?
I am not aware of an easy way to achieve this.
The "easiest" way I can think of is to walk the stack and find where the reference used as the target of the call is pushed.
Basically, starting from the call instruction go back one instruction at a time taking into account how each one affects the stack; this way you can find the exact instruction that pushes the reference used as the target of the call (a long time ago I wrote something like that; you can use the code at https://github.com/lytico/db4o/blob/master/db4o.net/Db4oTool/Db4oTool/Core/StackAnalyzer.cs as inspiration).
You'll need also to consider scenarios in which the pushed reference is produced through a method/property; for example, SomeFunction().f(5). In this case you may need to evaluate that method to find out the actual type returned.
Keep in mind that you'll need to handle a lot of different cases; for example, imagine the code bellow:
class Utils
{
public static T Instantiate<T>() where T : new() => new T();
}
class SomeType
{
public void F(int i) {}
}
class Usage
{
static void Main()
{
var o = Utils.Instantiate<SomeType>();
o.F(1);
}
}
while walking the stack you'll find that o is the target of the method call; then you'll evaluate Instantiate<T>() method and will find that it returns new T() and knowing that T is SomeType in this case, that is the type you're looking for.
So the answer of Vagaus helped me come up with a working implementation.
I published it on github - https://github.com/MarkKharitonov/MonoCecilExtensions
Included many unit tests, but I am sure I missed some cases.

Simple loop inside template -- variable 'x' cannot be read at compile time

(Note that I am extremely new to DLang (first day) so I am probably doing something very stupid)
I am trying to create a mixin template to re-use in my app's domain classes, which will automatically generate a toString1() method at compile-time, which will loop through the implementing struct's properties and generate code to print them.
To accomplish this, I am getting a const array of all of the struct's properties and trying to loop through them. However, when I try to access the index inside the loop (which should be perfectly executable at compile-time -- since we are looping against a known value) it fails.
It works completely fine if I use hard-coded indexes.
template Printable() {
import std.algorithm.iteration;
import std.conv;
import std.meta;
import std.stdio;
import std.format;
import std.range;
import std.typecons;
string toString1() const {
const auto traits = __traits(allMembers, typeof(this));
const auto internalWrap = (const string s) => "`" ~ s ~ ": ` ~ this." ~ s ~ " ~ `\n`";
const auto ret = iota(0, traits.length)
.map!((const int x) => traits[x]) // Error: variable x cannot be read at compile time
.fold((a, b) => a ~ b);
pragma(msg, internalWrap(traits[0])); // WORKS GREAT
return "";
}
}
(Just a note that I also tried doing it using both for-loops as well, but it fails with the same error).
I wanted to put an answer on this so this is a code example about what we went over in the comments:
struct A {
int a;
string b;
mixin Printable; // adds the toString1 method
}
mixin template Printable() {
string toString1() const {
string s;
import std.conv;
// loop over the trait directly, don't try to feed it
// through variables to ensure still available
foreach(memberName; __traits(allMembers, typeof(this))) {
// this ensures we are only actually trying to print actual fields
// (only fields have an offsetof property) since printing member
// variables will not be helpful
static if(is(typeof(__traits(getMember, this, memberName).offsetof))) {
if(s.length)
s ~= "\n";
// name
s ~= memberName;
s ~= " = ";
// value, converted to string
s ~= to!string(__traits(getMember, this, memberName));
}
}
return s;
}
}
void main() {
import std.stdio;
A a = A(14, "string");
writeln(a.toString1());
}
prints
a = 14
b = string

how to pass a reference to const pointer correctly?

I just wonder how I can efficiently pass a reference to const pointer to an object of a class.
For example,
class BigData
{
public:
int m[1000];
};
void Func(const BigData* const& bigData)
{
// just read bigData; No modification on bigData.
}
int main()
{
BigData* bigData = new BigData();
Func(bigData);
}
Above example, I do not quite understand why I have to put const before reference(&).
If I try to build it without the reference, the compiler complains about
cannot convert parameter 1 from 'BigData *' to 'const BigData *&'
Seems like it is related to R-value rule but I don't know what rule exactly governs this case.
TIA
}
Don't. Just pass the pointer by value. Syntactically it is easier for the called function to use, and will have less overhead.
void Func(const BigData *bigData)

How to use stdext::hash_map?

I would like to see a simple example of how to override stdext::hash_compare properly, in order to define a new hash function and comparison operator for my own user-defined type. I'm using Visual C++ (2008).
This is how you can do it
class MyClass_Hasher {
const size_t bucket_size = 10; // mean bucket size that the container should try not to exceed
const size_t min_buckets = (1 << 10); // minimum number of buckets, power of 2, >0
MyClass_Hasher() {
// should be default-constructible
}
size_t operator()(const MyClass &key) {
size_t hash_value;
// do fancy stuff here with hash_value
// to create the hash value. There's no specific
// requirement on the value.
return hash_value;
}
bool operator()(const MyClass &left, const MyClass &right) {
// this should implement a total ordering on MyClass, that is
// it should return true if "left" precedes "right" in the ordering
}
};
Then, you can just use
stdext::hash_map my_map<MyClass, MyValue, MyClass_Hasher>
Here you go, example from MSDN
I prefer using a non-member function.
The method expained in the Boost documentation article Extending boost::hash for a custom data type seems to work.

Resources