C# - Referencing "this int" parameter - c#

I have very simple Bitwise Operator methods that I want to use like this:
myInt.SetBit(int k, bool set)
so that it changes the bit at index 'k' to the value 'set' (0 or 1) I first thought of doing it like this:
public static void SetBit(this int A, int k, bool set) {
if (set) A |= 1 << k;
else A &= ~(1 << k);
}
but of course this only changes the internal value of variable 'A', and not the original variable, since integer isn't a reference type.
I can't use 'ref' along with 'this' so I don't know how to turn this into a reference parameter.
I already have similar methods for Int arrays, but those work fine since an array is a reference type.
I'm looking for a way to keep this handy syntax for single integers, if there is one.

You shouldn't treat it as a reference type.
Make your method return the modified value and assign it back to your variable. That approach will be consistent to immutable types. Consider example of String.Replace, it doesn't modify the string in place, instead it returns a modified copy.
public static int SetBit(this int A, int k, bool set)
{
if (set) A |= 1 << k;
else A &= ~(1 << k);
return A;
}

Some types (like ints) are immutable, meaning that once they are set to a value, they cannot be changed again. You'll notice that any method working on an int will return a new int rather than changing the value of the given value.
Update your code like this:
public static int SetBit(this int A, int k, bool set) {
if (set) A |= 1 << k;
else A &= ~(1 << k);
return A;
}
and use it like:
var x = 5;
x = x.SetBit(1, true);

I suggest just returning the result instead of trying to change immutable int:
// int instead of void
public static int SetBit(this int A, int k, bool set) {
return set ? (A | (1 << k)) : (A & (~(1 << k)));
}
So you can do
int source = 12345;
int result = source.SetBit(3, true);

I had to check on this because it looks a little odd. Sure enough - you can't write an extension method using ref.
See here, someone else has tried this.

You cannot mix this and ref in the extension methods. You have many choices:
Returning the result from the extension method (I prefer this option):
public static int SetBit(this int A, int k, bool set)
{
if (set) A |= 1 << k;
else A &= ~(1 << k);
return A;
}
using:
int i = 3;
i = i.SetBit(1, false);
Using a method with ref:
public static void SetBitRef(ref int A, int k, bool set)
{
if (set) A |= 1 << k;
else A &= ~(1 << k);
}
using:
int i = 3;
IntExtensions.SetBitRef(ref i, 1, false);
Using an IntWrapper class instead of int:
class IntWrapper
{
public IntWrapper(int intValue)
{
Value = intValue;
}
public int Value { get; set; }
}
with a reference type you can create this extension method:
public static void SetBit(this IntWrapper A, int k, bool set)
{
int intValue = A.Value;
if (set) intValue |= 1 << k;
else intValue &= ~(1 << k);
A.Value = intValue;
}
using:
IntWrapper iw = new IntWrapper(3);
iw.SetBit(1, false);

Related

C# hexadecimal to struct

I have different kinds of hexadecimals with a length of 8, like FFFFFFFA (4 bytes 255, 255, 255 and 250 ASCII encoded). Converting this one to binary gives: 11111111 11111111 11111111 11111010 where every digits stands for true (1) or false (0).
It would be nice to have some kind of object in C# where every property represent a binary. In this case a object with 32 bool properties.
Searching on the internet brought me to structs but I can't figure out how to do it.
Concrete questions: How can I convert hexadecimals to a struct and back?
Any direction would be nice!
Thanks in advance!
You can try System.Collections.BitArray
Some Demo:
using System.Collections;
using System.Linq;
...
int original = 123;
// Create array from int
BitArray array = new BitArray(new int[] {original});
// Access to the single Bit (which is represented as bool)
Console.WriteLine(array[0] ? "Y" : "N");
// Let's have a look at all bits within the array
Console.WriteLine(string.Concat(array.Cast<bool>().Select(x => x ? 1 : 0)));
// Restore int from the array
int back = array
.Cast<bool>()
.Reverse()
.Aggregate(0, (s, a) => s * 2 + (a ? 1 : 0));
Console.WriteLine(back);
Outcome:
Y
11011110000000000000000000000000
123
How can I convert hexadecimals to a struct and back?
I suppose it depends what form your hex numbers take; you seem to have ints, so you could wrap an integer with some convenience props that just mask the bits off or on:
struct Biteger{
private int _x;
public bool Bit0 {
get => this[0];
set => this[0] = value;
}
public bool Bit1 {
get => this[1];
set => this[1] = value;
}
//...
public bool this[int index]{
get => (_x & (1 << index)) != 0;
set { _x = value ? _x | (1 << index) : _x & ~(1 << index); }
}
public static implicit operator int(Biteger b) => b._x;
public static implicit operator Biteger(int i) => new Biteger{ _x = i };
}
And you could use it like:
Biteger x = 0x81; //sets bits 7 and 0 for 0x81
x[6] = true; //sets bit 6 for adding 0x40
x.Bit5 = true; //sets bit 5 for adding 0x20
Console.WriteLine(((int)x).ToString("x")); //prints e1
If you wanted to keep your data in a bit array it might look like
public struct Biteger{
private BitArray _ba;
public bool Bit0 {
get => _ba[0];
set { _ba[0] = value; }
}
...
public bool Bit31 {
get => _ba[31];
set { _ba[31] = value; }
}
public bool this[int index]{
get => _ba[index];
set { _ba[index] = value; }
}
public implicit operator int(Biteger b){
int x = 0;
for(int i = 0; i < 32; i++) if (b._ba[i]) x |= 1 << i;
return x;
}
public static implicit operator Biteger(int i) => return new Biteger{ _ba = new(new[]{i}) };
}
Thank you for all the comments and samples. I ended up with using BitVector32 because it's more efficient for boolean values and small integers (memory and performance overhead for more info: https://learn.microsoft.com/en-us/dotnet/api/system.collections.specialized.bitvector32?view=net-6.0)
Struct
// Size = 4 because BitVector32 is 4 bytes
[StructLayout(LayoutKind.Explicit, Size = 4, CharSet = CharSet.Ansi)]
public struct Foo
{
public Foo() {
// Creates and initializes a BitVector32.
// 4 bytes
// 00000000 00000000 00000000 00000000
data = new BitVector32(0);
bit1 = BitVector32.CreateMask();
bit2 = BitVector32.CreateMask(bit1);
bit3 = BitVector32.CreateMask(bit2);
// ...
}
[FieldOffset(0)]
public BitVector32 data;
private static int bit1;
private static int bit2;
private static int bit3;
public bool Bit1
{
get => data[bit1];
set => data[bit1] = value;
}
public bool Bit2
{
get => data[bit2];
set => data[bit2] = value;
}
public bool Bit3
{
get => data[bit3];
set => data[bit3] = value;
}
public string ToHexString()
{
return data.Data.ToString("X");
}
}
Program
// -- Hex to struct
// FFFFBBFF
// 255 255 187 255
// 11111111 11111111 10111011 11111111
// var bytes = "FFFFBBFF".ToBytes();
var bytes = { 255, 255, 187, 255 };
var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
var foo = (Foo)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Foo));
handle.Free();
Console.WriteLine(foo.Bit1);
Console.WriteLine(foo.Bit2);
Console.WriteLine(foo.Bit3);
// ...
// -- Or struct to hex
var foo = new Foo();
foo.Bit1 = true;
foo.Bit2 = false;
foo.Bit3 = true;
// ...
Console.WriteLine(foo.ToHexString());
I know it's not perfect, it works for me and I hope it will help others.
Have a nice day!

C# Poor dictionary performance when adding elements

I have a big chunck of data containing ~1.5 million entries. Each entry is an instance of a class like this:
public class Element
{
public Guid ID { get; set; }
public string name { get; set; }
public property p... p1... p2...
}
I have a list of Guids (~4 millions) that I need to get the names based on a list of instances of the Element class.
I'm storing the Element objects in a Dictionary, but it takes ~90 seconds to populate the data. Is there any way to improve performance when adding items to the dictionary? The data doesn't have duplicates but I know that the dictionary checks for duplicates when adding a new item.
The structure doesn't need to be a dictionary if there's a better one. I tried to put the Element objects in a List which performed a lot better (~9sec) when adding. But then when I need to look for the item with a certain Guid it takes more than 10min to find all the 4million elements. I tried that using List.Find() and manually iterating through the list.
Also, if instead of using System.Guid I convert them all to String and store their string representation on the data structures the whole both operations of populating the dictionary and filling the names on the other list takes only 10s, but then my application consumes 1.2Gb of RAM, instead of 600mb when I store them as System.Guid.
Any ideas on how to perform it better?
Your problem is perhaps connected to "sequential" Guid, like:
c482fbe1-9f16-4ae9-a05c-383478ec9d11
c482fbe1-9f16-4ae9-a05c-383478ec9d12
c482fbe1-9f16-4ae9-a05c-383478ec9d13
c482fbe1-9f16-4ae9-a05c-383478ec9d14
c482fbe1-9f16-4ae9-a05c-383478ec9d15
The Dictionary<,> has a problem with those, because they often have the same GetHashCode(), so it has to do some tricks that change the search time from O(1) to O(n)... You can solve it by using a custom equality comparer that calculates the hash in a different way, like:
public class ReverseGuidEqualityComparer : IEqualityComparer<Guid>
{
public static readonly ReverseGuidEqualityComparer Default = new ReverseGuidEqualityComparer();
#region IEqualityComparer<Guid> Members
public bool Equals(Guid x, Guid y)
{
return x.Equals(y);
}
public int GetHashCode(Guid obj)
{
var bytes = obj.ToByteArray();
uint hash1 = (uint)bytes[0] | ((uint)bytes[1] << 8) | ((uint)bytes[2] << 16) | ((uint)bytes[3] << 24);
uint hash2 = (uint)bytes[4] | ((uint)bytes[5] << 8) | ((uint)bytes[6] << 16) | ((uint)bytes[7] << 24);
uint hash3 = (uint)bytes[8] | ((uint)bytes[9] << 8) | ((uint)bytes[10] << 16) | ((uint)bytes[11] << 24);
uint hash4 = (uint)bytes[12] | ((uint)bytes[13] << 8) | ((uint)bytes[14] << 16) | ((uint)bytes[15] << 24);
int hash = 37;
unchecked
{
hash = hash * 23 + (int)hash1;
hash = hash * 23 + (int)hash2;
hash = hash * 23 + (int)hash3;
hash = hash * 23 + (int)hash4;
}
return hash;
}
#endregion
}
Then you simply declare the dictionary like this:
var dict = new Dictionary<Guid, Element>(ReverseGuidEqualityComparer.Default);
a little test to see the difference:
private static void Increment(byte[] x)
{
for (int i = x.Length - 1; i >= 0; i--)
{
if (x[i] != 0xFF)
{
x[i]++;
return;
}
x[i] = 0;
}
}
and
// You can try timing this program with the default GetHashCode:
//var dict = new Dictionary<Guid, object>();
var dict = new Dictionary<Guid, object>(ReverseGuidEqualityComparer.Default);
var hs1 = new HashSet<int>();
var hs2 = new HashSet<int>();
{
var guid = Guid.NewGuid();
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 1500000; i++)
{
hs1.Add(ReverseGuidEqualityComparer.Default.GetHashCode(guid));
hs2.Add(guid.GetHashCode());
dict.Add(guid, new object());
var bytes = guid.ToByteArray();
Increment(bytes);
guid = new Guid(bytes);
}
sw.Stop();
Console.WriteLine("Milliseconds: {0}", sw.ElapsedMilliseconds);
}
Console.WriteLine("ReverseGuidEqualityComparer distinct hashes: {0}", hs1.Count);
Console.WriteLine("Guid.GetHashCode() distinct hashes: {0}", hs2.Count);
With sequential Guid the difference in the number of distinct hash codes is staggering:
ReverseGuidEqualityComparer distinct hashes: 1500000
Guid.GetHashCode() distinct hashes: 256
Now... If you don't want to use ToByteArray() (because it allocates useless memory), there is a solution that uses reflection and expression trees... It should work correctly with Mono, because Mono "aligned" its implementation of Guid to the one of Microsoft in 2004, that is ancient time :-)
public class ReverseGuidEqualityComparer : IEqualityComparer<Guid>
{
public static readonly ReverseGuidEqualityComparer Default = new ReverseGuidEqualityComparer();
public static readonly Func<Guid, int> GetHashCodeFunc;
static ReverseGuidEqualityComparer()
{
var par = Expression.Parameter(typeof(Guid));
var hash = Expression.Variable(typeof(int));
var const23 = Expression.Constant(23);
var const8 = Expression.Constant(8);
var const16 = Expression.Constant(16);
var const24 = Expression.Constant(24);
var b = Expression.Convert(Expression.Convert(Expression.Field(par, "_b"), typeof(ushort)), typeof(uint));
var c = Expression.Convert(Expression.Convert(Expression.Field(par, "_c"), typeof(ushort)), typeof(uint));
var d = Expression.Convert(Expression.Field(par, "_d"), typeof(uint));
var e = Expression.Convert(Expression.Field(par, "_e"), typeof(uint));
var f = Expression.Convert(Expression.Field(par, "_f"), typeof(uint));
var g = Expression.Convert(Expression.Field(par, "_g"), typeof(uint));
var h = Expression.Convert(Expression.Field(par, "_h"), typeof(uint));
var i = Expression.Convert(Expression.Field(par, "_i"), typeof(uint));
var j = Expression.Convert(Expression.Field(par, "_j"), typeof(uint));
var k = Expression.Convert(Expression.Field(par, "_k"), typeof(uint));
var sc = Expression.LeftShift(c, const16);
var se = Expression.LeftShift(e, const8);
var sf = Expression.LeftShift(f, const16);
var sg = Expression.LeftShift(g, const24);
var si = Expression.LeftShift(i, const8);
var sj = Expression.LeftShift(j, const16);
var sk = Expression.LeftShift(k, const24);
var body = Expression.Block(new[]
{
hash
},
new Expression[]
{
Expression.Assign(hash, Expression.Constant(37)),
Expression.MultiplyAssign(hash, const23),
Expression.AddAssign(hash, Expression.Field(par, "_a")),
Expression.MultiplyAssign(hash, const23),
Expression.AddAssign(hash, Expression.Convert(Expression.Or(b, sc), typeof(int))),
Expression.MultiplyAssign(hash, const23),
Expression.AddAssign(hash, Expression.Convert(Expression.Or(d, Expression.Or(se, Expression.Or(sf, sg))), typeof(int))),
Expression.MultiplyAssign(hash, const23),
Expression.AddAssign(hash, Expression.Convert(Expression.Or(h, Expression.Or(si, Expression.Or(sj, sk))), typeof(int))),
hash
});
GetHashCodeFunc = Expression.Lambda<Func<Guid, int>>(body, par).Compile();
}
#region IEqualityComparer<Guid> Members
public bool Equals(Guid x, Guid y)
{
return x.Equals(y);
}
public int GetHashCode(Guid obj)
{
return GetHashCodeFunc(obj);
}
#endregion
// For comparison purpose, not used
public int GetHashCodeSimple(Guid obj)
{
var bytes = obj.ToByteArray();
unchecked
{
int hash = 37;
hash = hash * 23 + (int)((uint)bytes[0] | ((uint)bytes[1] << 8) | ((uint)bytes[2] << 16) | ((uint)bytes[3] << 24));
hash = hash * 23 + (int)((uint)bytes[4] | ((uint)bytes[5] << 8) | ((uint)bytes[6] << 16) | ((uint)bytes[7] << 24));
hash = hash * 23 + (int)((uint)bytes[8] | ((uint)bytes[9] << 8) | ((uint)bytes[10] << 16) | ((uint)bytes[11] << 24));
hash = hash * 23 + (int)((uint)bytes[12] | ((uint)bytes[13] << 8) | ((uint)bytes[14] << 16) | ((uint)bytes[15] << 24));
return hash;
}
}
}
Other solution, based on "undocumented but working" programming (tested on .NET and Mono):
public class ReverseGuidEqualityComparer : IEqualityComparer<Guid>
{
public static readonly ReverseGuidEqualityComparer Default = new ReverseGuidEqualityComparer();
#region IEqualityComparer<Guid> Members
public bool Equals(Guid x, Guid y)
{
return x.Equals(y);
}
public int GetHashCode(Guid obj)
{
GuidToInt32 gtoi = new GuidToInt32 { Guid = obj };
unchecked
{
int hash = 37;
hash = hash * 23 + gtoi.Int32A;
hash = hash * 23 + gtoi.Int32B;
hash = hash * 23 + gtoi.Int32C;
hash = hash * 23 + gtoi.Int32D;
return hash;
}
}
#endregion
[StructLayout(LayoutKind.Explicit)]
private struct GuidToInt32
{
[FieldOffset(0)]
public Guid Guid;
[FieldOffset(0)]
public int Int32A;
[FieldOffset(4)]
public int Int32B;
[FieldOffset(8)]
public int Int32C;
[FieldOffset(12)]
public int Int32D;
}
}
It uses the StructLayout "trick" to superimpose a Guid to a bunch of int, write to the Guid and read the int.
Why does Guid.GetHashCode() has problems with sequential ids?
Very easy to explain: from the reference source, the GetHashCode() is:
return _a ^ (((int)_b << 16) | (int)(ushort)_c) ^ (((int)_f << 24) | _k);
so the _d, _e, _g, _h, _i, _j bytes aren't part of the hash code. When incremented a Guid is first incremented in the _k field (256 values), then on overflow in the _j field (256 * 256 values, so 65536 values), then on the _i field (16777216 values). Clearly by not hashing the _h, _i, _j fields the hash of a sequential Guid will only show 256 different values for non-huge range of Guid (or at maximum 512 different values, if the _f field is incremented once, like if you start with a Guid similar to 12345678-1234-1234-1234-aaffffffff00, where aa (that is "our" _f) will be incremented to ab after 256 increments of the Guid)
I'm not, the dictionary Key is the ID property of the Element class, and not the Element class itself. This property is of type System.Guid.
The problem with Guid is that it's a very specialized construct. For one thing it's a struct, not a class. Moving this thing around isn't as simple as moving a pointer (technically a handle, but same thing), it involves moving the entire memory block around. Keep in mind the .NET memory model makes everything be compact, so that also involves moving other blocks around to make room.
Also looking at the source code, it stores all the parts as separate fields, 11 of them! That's a lot of comparisons for 1.5 million entries.
What I'd do is create a sort of alternate Guid implementation (class, not struct!) tailor made for efficient comparisons. All the fancy parsing isn't needed, just focus on speed. Guids are 16 bytes in length, that means 4 long fields. You need to implement Equals as usual (compare the 4 fields) and GetHashCode as something like XORing the fields. I'm certain that's good enough.
Edit: Note that I'm not saying the framework-provided implementation is bad, it's just not made for what you're trying to do with it. In fact it's terrible for your purpose.
If your data is pre-sorted, You can use List<T>.BinarySearch to quickly search in the list. You will need to create a comparer class, and use it for looking up.
class ElementComparer : IComparer<Element>
{
public int Compare(Element x, Element y)
{
// assume x and y is not null
return x.ID.CompareTo(y.ID);
}
}
Then use it
var comparer = new ElementComparer();
var elements = new List<Element>(1500000); // specify capacity might help a bit
//... (load your list here. Sort it with elements.Sort(comparer) if needed)
Guid guid = elements[20]; // for the sake of testing
int idx = elements.BinarySearch(new Element { ID = guid }, comparer);
You can wrap this whole thing in IReadOnlyDictionary<Guid, Element> if you want, but maybe you don't need it this case.

Passing Empty Array/Multiple Integers To Function And Returning Them

Lets say I have array (array[20]) and I want to pass it to function which will fill it with random numbers and return it.
How do I pass an empty array to function and how do I return it after function is done?
Also, lets assume I have 3 different integers ( int a = 3; int b = 2; int c = 5;)
How do I pass all 3 integers to function and return them after function is done?
I've just started learning functions, and so far I only know how to pass 2 different integers and return one.
I know exactly what to write into functions, but I just don't know how to pass the variables/empty array.
An array is a reference type, so you just pass it and modify it. The changes (other than assigning the variable) will propagate to the caller:
private void MyFunc(int[] array)
{
//Some generation
array[0] = 1; //Generated by fair dice roll
//Guaranteed to be random
}
For the integers, you need to actually pass by ref for changes to get back to the caller. You can't return more than one value, so you either pass by ref, return them as a Tuple or return a custom class. Given your experience level, you probably want the ref option:
private void MyFunc2(ref int i, ref int j, ref int k)
{
i = 3;
j = 4;
k = 5;
}
MyFunc2(ref var1, ref var2, ref var3);
You normally don't do this, so consider your use case carefully.
Documentation for ref: MSDN
I wonder why you want to do this, but anyway...
How do I pass an empty array to function and how do I return it after function is done?
Simply return the same parameter after doing the job:
int[] emptyArr = new int[20];
yourFunction(emptyArr);
int[] yourFunction(int[] arr) {
//Do your work
return arr;
}
Note that you don't even need to return arr, neither declare the funcion as int[], since whatever you do with the arr variable will affect the emptyArr. It's a reference.
In C# there are references and values. int[] is a reference. Check it out: http://www.albahari.com/valuevsreftypes.aspx
How do I pass all 3 integers to function and return them after function is done?
void numbers( ref int a, ref int b, ref int c) { //do your thing here }
You shouldn't write ref int a, ref int b, ref int c, you will learn someday about side-effects and application state in functional programming. But anyway, it's OK for learning.
The array will be passed by reference so you can pass it in and fill it and simply return.
To return the three int values you can pass them by reference, ref, or you can also set up a set of integer to return the value in and flag them as out. Using out passes the values of the original data and forces you to set the values of the referenced returned integers.
static void passInts(ref int a, ref int b, ref int c)
{
a = a + b;
b = b + c;
c = c + 2;
}
static void passInts(int a, int b, int c, out int a1, out int b1, out int c1)
{
a1 = a + b;
b1 = b + c;
c1 = c + 2;
}
int a = 1;
int b = 2;
int c= 3;
Console.WriteLine(string.Format("a={0}, b={1}, c={2}", a, b, c));
passInts(ref a, ref b, ref c);
Console.WriteLine(string.Format("a={0}, b={1}, c={2}", a, b, c));
int A,B,C;
passInts(a, b, c, out A, out B, out C);
Console.WriteLine(string.Format("a={0}, b={1}, c={2}", A,B,C));

Convert double to UInt16

I'm making a function that will allow the user to pass a double value, and then return a UInt16.
This is my code:
public static UInt16 Value_To_BatteryVoltage(double value)
{
var ret = ((int)value << 8);
var retMod = (value % (int)value) * 10;
return (UInt16)(ret + retMod);
}
Basically what it does is as follows, function call:
Value_To_BatteryVoltage(25.10)
Will return: 6401
I can check the result by doing:
public static double VoltageLevel(UInt16 value)
{
return ((value & 0xFF00) >> 8) + ((value & 0x00FF) / 10.0);
}
This is working as expected, BUT, if I do:
Value_To_BatteryVoltage(25.11) //notice the 0.11
I get the wrong result, because:
public static UInt16 Value_To_BatteryVoltage(double value)
{
var ret = ((int)value << 8); // returns 6400 OK
var retMod = (value % (int)value) * 10; //returns 0.11 x 10 = 1.1 WRONG!
return (UInt16)(ret + retMod); //returns 6400, because (UInt16)(6400 + 1.1) = 6401 same as 25.10 so I've lost precision
}
So the question is, is there some way to do this kind of conversion without losing precision?
If I understand the question, you want to store the Characteristic (interger-part) in the first 8 bits of UInt16. And the Mantissa (fractional-part) in the second 8 bits.
This is one way to do it. I treat the double like a string and split it at the decimal. For example:
public static UInt16 Value_To_BatteryVoltage(double value)
{
string[] number = value.ToString().Split('.');
UInt16 c = (UInt16)(UInt16.Parse(number[0]) << 8);
UInt16 m = UInt16.Parse(number[1]);
return (UInt16)(c + m);
}
And here is the output:

C++ Equivalent of C# Yield?

public void Consumer()
{
foreach(int i in Integers())
{
Console.WriteLine(i.ToString());
}
}
public IEnumerable<int> Integers()
{
yield return 1;
yield return 2;
yield return 4;
yield return 8;
yield return 16;
yield return 16777216;
}
Is there a way with template trick (or other) to get the same syntax in c++?
Take a look at boost::Coroutine. It does what you want.
http://www.crystalclearsoftware.com/soc/coroutine/index.html#coroutine.intro
Example from tutorial
http://www.crystalclearsoftware.com/soc/coroutine/coroutine/tutorial.html
int range_generator(generator_type::self& self, int min, int max)
{
while(min < max)
self.yield(min++);
self.exit();
}
You can always code this by hand. Truthfully, yield really seems like sugar coating to me (and co-routines too).
What a coroutine is, really ? Some state bundled up together with:
one function to create it (isn't it a constructor ?)
one function to move to the next state (isn't it operator++, traditionally ?)
In C++, it's called an InputIterator, and can be arbitrarily fat.
So, it's true that the syntax won't be as pretty, but this should do, just with the Standard Library:
static std::array<int, 6> const Array = {{1, 2, 4, 8, 16, 16777216}};
class Integers: public std::iterator<std::input_iterator_tag,
int, ptrdiff_t, int const*, int>
{
public:
Integers(): _index(0) {}
operator bool() const { return _index < Array.size(); }
Integers& operator++() { assert(*this); ++_index; return *this; }
Integers operator++(int) { Integers tmp = *this; ++*this; return tmp; }
int operator*() const { assert(*this); return Array[_index]; }
int const* operator->() const { assert(*this); return &Array[_index]; }
private:
size_t _index;
}; // class Integers
And obviously, since you decide exactly what state is stored, you decide if all is pre-computed or if part (or whole of it) is lazily computed, and possibly cached, and possibly multi-threaded, and ... you got the idea :)
In C++14, you can mimic yield this way:
auto&& function = []() {
int i = 0;
return [=]() mutable {
int arr[] = { 1, 2, 4, 8, 16, 16777216};
if (i < 6)
return arr[i++];
return 0;
};
}();
A live example is available at http://ideone.com/SQZ1qZ
Coroutines are in the standard library since C++20 and uses co_yield instead of yield.
See also: What are coroutines in C++20?
There are some example usages in the first link: (the second one is probably what you're looking for)
uses the co_await operator to suspend execution until resumed
task<> tcp_echo_server() {
char data[1024];
while (true) {
size_t n = co_await socket.async_read_some(buffer(data));
co_await async_write(socket, buffer(data, n));
}
}
uses the keyword co_yield to suspend execution returning a value
generator<int> iota(int n = 0) {
while (true)
co_yield n++;
}
uses the keyword co_return to complete execution returning a value
lazy<int> f() {
co_return 7;
}
Here is ASM "roll your own" version : http://www.flipcode.com/archives/Yield_in_C.shtml
#include <stdio.h
#include <conio.h
#include <iostream.h
//
// marks a location in the program for resume
// does not return control, exits function from inside macro
//
// yield( x, ret )
// x : the 'name' of the yield, cannot be ambiguous in the
// function namespace
// ret : the return value for when yield() exits the function;
// must match function return type (leave blank for no return type)
#define yield(x,ret) \
{ \
/* store the resume location */ \
__asm { \
mov _myStaticMkr,offset label_##x \
} \
\
/* return the supplied value */ \
return ret; \
} \
/* our offset in the function */ \
label_##x:
//
// resumes function from the stored offset, or
// continues without notice if there's not one
// stored
//
// resume()
// <void
#define resume() \
/* our stored offset */ \
static _myStaticMkr=0; \
\
/* test for no offset */ \
if( _myStaticMkr ) \
{ \
/* resume from offset */ \
__asm \
{ \
jmp _myStaticMkr \
} \
}
// example demonstrating a function with an int return type
// using the yield() and resume() macros
//
// myFunc()
// <void
int myFunc()
{
resume();
cout << "1\n";
yield(1,1);
cout << "2\n";
yield(2,1);
cout << "3\n";
yield(3,1);
cout << "4\n";
return 0;
}
// main function
//
// main()
// <void
void main( void )
{
cout << "Yield in C++\n";
cout << "Chris Pergrossi\n\n";
myFunc();
do
{
cout << "main()\n";
cout.flush();
} while( myFunc() );
cout.flush();
getch();
}
/*
// example demonstrating a function with no return type
// using the yield() and resume() macros
//
// myFunc()
// <void
void myFunc()
{
resume();
cout << "1\n";
yield(1);
cout << "2\n";
yield(2);
cout << "3\n";
yield(3);
cout << "4\n";
return;
}
// main function
//
// main()
// <void
void main( void )
{
cout << "Yield in C++\n";
cout << "Chris Pergrossi\n\n";
myFunc();
for( int k = 0; k < 4; k ++ )
{
cout << "main()\n";
cout.flush();
myFunc();
}
cout.flush();
getch();
}
*/
If all what you need is just foreach-like stuff, then following syntax is available in C++:
#define GENERATOR(name) \
struct name \
{ \
template<typename F> \
void operator()(F yield) \
/**/
#define _ };
template<typename Gen>
struct Adaptor
{
Gen f;
template<typename C>
void operator*(C cont)
{
f(cont);
}
};
template<typename Gen>
Adaptor<Gen> make_adaptor(Gen gen)
{
return {gen};
}
#define FOREACH(arg, gen) make_adaptor(gen) * [&](arg)
#include <iostream>
using namespace std;
GENERATOR(integers)
{
yield(1);
yield(2);
yield(4);
yield(8);
yield(16777216);
}_
int main()
{
FOREACH(int i, integers())
{
cout << i << endl;
};
}
Live Demo
If you need a little bit of coroutine "power", then you can try stackless coroutines.
Or if you need full power - then go with stackful coroutines. There is Boost.Coroutine library which implements stackful coroutines for different platforms.
An try to implement yield in c++ coroutine
If you write static unsigned int checkpoint = 0;, make all your variables static, switch (checkpoint), set each case: goto to some label, above each return set checkpoint to unique value, and below define label, and at the end of the function set checkpoint to zero, and all static variables to their default value, and at last return the end value of the function. If you do all this then the function becomes enumerable and iterative. The two lines you add above and below each return line, makes the return command to behave like yield return. goto allows you to continue and resume where you left off, and static integer variable, like checkpoint, help you to remember where you stopped, from where to continue/resume and where to go. You test it's values with switch case statements. Making all other variables static, is to save their value to the next call, so in the next call, their value won't be reset!
Here for example:
#define PowerEnd INT_MIN
int Power(int number, int exponent)
{
static unsigned int checkpoint = 0;
static int result = 1, i = 0;
switch (checkpoint)
{
case 1: goto _1;
}
for (i = 0; i < exponent; i++)
{
result *= number;
checkpoint = 1;
return result;
_1:;
}
checkpoint = 0;
result = 1;
i = 0;
return PowerEnd;
}
void main()
{
while (true)
{
int result = Power(2, 8);
if (result == PowerEnd)
break;
cout << result << endl;
}
//to print only the first 4 results (if there are at least 4 results) then
for (int i = 0; i < 4; i++)
{
int result = Power(2, 8);
if (result == PowerEnd)
break;
cout << result << endl;
}
}
The above program produces the following output:
2
4
8
16
32
64
128
256
2
4
8
16
Something similar is proposed for C++17 and there is already an experimental implementation in Visual C++ 2015. Here's a good overview talk from Gor Nishanov, one of the main authors of the proposal.
#include <setjmp.h>
class superclass
{
public:
jmp_buf jbuf;
public:
virtual int enumerate(void) { return -1; }
};
class subclass: public superclass
{
public:
int enumerate()
{
static int i;
static bool b = false;
if(b)
longjmp(jbuf, 1);
for(b = true, i = 0; i < 5; (i)++)
{
printf("\ndoing stuff: i = %d\n", i);
if(setjmp(jbuf) != 1)
return i;
}
return -1;
}
};
To use the code...
int iret;
subclass *sc;
sc = new subclass();
while((iret = sc->enumerate()) != -1)
{
printf("\nsc->enumerate() returned: %d\n", iret);
}
Just got this working; it seems quite simple now, although I had a few false starts with it :)
You can of course always write your own iterators and return from them whatever you desire, but why would you want to? In the given example, why not simply put your values into a container like vector and iterate over that?

Categories

Resources