How can I add a reference to a value-type in vala - memory-management

In c++ I can add a reference to a value type, for example :
int a = 12;
int &b = a;
a--;
cout << "a = " << a << ", b = " << b << endl;
Will give :
a = 11, b = 11
Is there a way to do the same in vala without using pointers ?

Is there a way to do the same in vala
Yes.
without using pointers ?
No.
If, however, you are passing them to a function, you can use a ref parameter:
void decrement (ref value) {
value--;
}
void do_stuff () {
int a = 12;
decrement (ref a);
assert (a == 11);
}

Related

c++11 how to check template parameter pack has N args before calling function with N args

Following on from this extracting a template parameter pack with different types into a vector of doubles produces warnings and cigien's answer.
I have the following code:
enum class p_type {p1, p2, p3};
class testerx
{
public:
void process1(double a)
{
std::cout << "1" << a << std::endl;
};
void process2(double a, double b)
{
std::cout << "2" << a << " " << b << std::endl;
};
void process3(double a, double b, double c)
{
std::cout << "3" << a << " " << b << " " << c << std::endl;
};
};
// The template type
template<typename TESTER, typename... ARGS>
class tester_templatex
{
public:
explicit tester_templatex(p_type type) : m_type(type) {};
void process(ARGS... args)
{
// Create a vector to put the args into. use double since that can hold all of the types
// that I am using
size_t param_count = sizeof...(args);
std::cout << "PARAM COUNT X " << param_count << std::endl;
std::vector<double> args_vect = {static_cast<double>(args)...};
for (auto arg : args_vect)
{
std::cout << "arg: " << arg << std::endl;
}
// Now call the tester
std::cout << "running tester: ";
switch (m_type)
{
case p_type::p1:
if constexpr (sizeof...(args) == 1)
m_tester.process1(args...);
break;
case p_type::p2:
if constexpr (sizeof...(args) == 2)
m_tester.process2(args...);
break;
case p_type::p3:
if constexpr (sizeof...(args) == 3)
m_tester.process3(args...);
break;
}
std::cout << std::endl;
};
p_type m_type;
TESTER m_tester;
};
main:
int main() {
tester_templatex<testerx, int> templatex1(p_type::p1);
tester_templatex<testerx, int, double> templatex2(p_type::p2);
tester_templatex<testerx, int, double, int> templatex3(p_type::p3);
templatex1.process(4);
templatex2.process(4, 5.123);
templatex3.process(4, 5.123, 6);
return 0;
}
Here I have test class with 3 different functions. I have a template class which picks the function to call based on the p_type (bad name - dont ask!).
This works for c++17 compiled code. But I only have c++11 where I need to run this code. c++11 does not support if constexpr:
case p_type::p3:
if constexpr (sizeof...(args) == 3)
m_tester.process3(args...);
break;
Without the if constexpr I get errors that the m_tester.process1/2/3 functions that don't match the parameter pack because they don't have the right number of parameters.
How can I fix this for c++11? - is it possible with a similar method?
Is there another way to extract N arguments from a parameter pack in c++11? - or some sort of type traits check?
For each of your functions have an overload that does nothing:
template<typename... ARGS>
void process3(ARGS&...) { }
and then just call the function without testing for the size of the pack:
case p_type::p3:
m_tester.process3(args...);
break;
This should pick the non-templated function when there are suitably many arguments, and the function template in other cases.

Calling a Method Multiple Times (C++)

so, i have a main method
int main () {
int x = 0;
inc(x);
inc(x);
inc(x);
std::cout << x << std::endl;
}
I'm trying to get my output to be '3' but can't figure out why everytime inc(x) is called x resets to 0.
my inc method:
int inc(int x){
++x;
std::cout << "x = " << x << std::endl;
return x;
}
my output:
x = 1
x = 1
x = 1
0
Why does x reset after every call to inc(x) and how can i fix this without editing my main function
Instead of
inc(x);
I think you need
x = inc(x);
You may slap your head now.
You're passing "x" to inc() by value, so changes made in inc() won't be visible in main().
If you want x to be changed you need to pass it by reference and not as a value. Also inc() would need to return void for that to make sense. here is an example.
// adding & before x passes the reference to x
void inc(int &x){
++x;
std::cout << "x = " << x << std::endl;
}
int main() {
int x = 0;
inc(x);
inc(x);
inc(x);
std::cout << x << std::endl;
}
this prints
x = 1
x = 2
x = 3
3

What does String do that I'm not doing? c++11

I am still new to c++, so bear with me.
I was trying to learn more about how std::move works and I saw an example where they used std::move to move the string to a different function and then showed using std::cout that no string remained. I thought cool, let's see if I can make my own class and do the same:
#include <iostream>
#include <string>
class integer
{
private:
int *m_i;
public:
integer(int i=0) : m_i(new int{i})
{
std::cout << "Calling Constructor\n";
}
~integer()
{
if(m_i != nullptr) {
std::cout << "Deleting integer\n";
delete m_i;
m_i = nullptr;
}
}
integer(integer&& i) : m_i(nullptr) // move constructor
{
std::cout << "Move Constructor\n";
m_i = i.m_i;
i.m_i = nullptr;
}
integer(const integer& i) : m_i(new int) { // copy constructor
std::cout << "Copy Constructor\n";
*m_i = *(i.m_i);
}
//*
integer& operator=(integer&& i) { // move assignment
std::cout << "Move Assignment\n";
if(&i != this) {
delete m_i;
m_i = i.m_i;
i.m_i = nullptr;
}
return *this;
}
integer& operator=(const integer &i) { // copy assignment
std::cout << "Copy Assignment\n";
if(&i != this) {
m_i = new int;
*m_i = *(i.m_i);
}
return *this;
}
int& operator*() const { return *m_i; }
int* operator->() const { return m_i; }
bool empty() const noexcept {
if(m_i == nullptr) return true;
return false;
}
friend std::ostream& operator<<(std::ostream &out, const integer i) {
if(i.empty()) {
std::cout << "During overload, i is empty\n";
return out;
}
out << *(i.m_i);
return out;
}
};
void g(integer i) { std::cout << "G-wiz - "; std::cout << "The g value is " << i << '\n'; }
void g(std::string s) { std::cout << "The g value is " << s << '\n'; }
int main()
{
std::string s("Hello");
std::cout << "Now for string\n";
g(std::move(s));
if(s.empty()) std::cout << "s is empty\n";
g(s);
std::cout << "\nNow for integer\n";
integer i = 77;
if(!i.empty()) std::cout << "i is " << i << '\n';
else std::cout << "i is empty\n";
g(i);
std::cout << "Move it\n";
g(std::move(i)); // rvalue ref called
if(!i.empty()) std::cout << "i is " << i << '\n';
else std::cout << "i is empty\n";
g(i);
return 0;
}
And this is my output:
Now for string
The g value is Hello
s is empty
The g value is
Now for integer
Calling Constructor
Copy Constructor
i is 77
Deleting integer
Copy Constructor
G-wiz - Copy Constructor
The g value is 77
Deleting integer
Deleting integer
Move it
Move Constructor
G-wiz - Copy Constructor
The g value is 77
Deleting integer
Deleting integer
i is empty
Copy Constructor
Process returned 255 (0xFF) execution time : 7.633 s
Press any key to continue.
As you can see, it crashes when it enters g the second time, never even getting to the operator<<() function. How is it that the empty std::string s can be passed to g where my empty integer i crashes the program?
Edit: Fixed new int vs. new int[] error. Thanks n.m.
Your "empty integer" crashes the program because it contains a null pointer. You are trying to dereference it when you use it at the right hand side of the assignment.
An empty string is a normal usable string. There are no unchecked null pointer dereferences in the std::string code.
You have to ensure that the empty state of your object is a usable one. Start with defining a default constructor. Does it make sense for your class? If not, then move semantic probably doesn't either. If yes, a moved-from object in the move constructor should probably end up in the same state as a default-constructed object. A move assignment can act as a swap operation, so there the right-hand-side may end up either empty or not.
If you don't want to define a usable empty state for your class, and still want move semantics, you simply cannot use an object after it has been moved from. You still need to make sure that an empty object is destructible.

Is it possible in C++11 to combine functions into a new function?

This is more a kind of theoretical question. Is it possible in C++11 to combine functions into a new function? For example :
auto f = [](int i){return i * 2;};
auto g = [](int i){return i + 10;};
So this works:
auto c = f(g(20)); // = 60
But I want an object that stores the combination, like
auto c = f(g);
std::cout << c(20) << std::endl; //prints 60
Edit:
Additionally what i want to create is a function a, which you can give a function b and an int n, and which returns the n'th combination of the given function b. For example (not compilable)
template<typename T>
auto combine(T b, int i) -> decltype(T)
{
if (i == 0)
return b;
return combine(b, i - 1);
}
auto c = combine(f, 2); //c = f(f(f(int)))
A first attempt:
template<class First, class Second>
auto compose( Second&& second, First&& first ) }
return [second = std::forward<Second>(second), first=std::forward<First>(first)]
(auto&&...args)->decltype(auto) {
return second( first( decltype(args)(args)... ) );
};
}
template<class A, class B, class...Rest>
auto compose(A&& a, B&& b, Rest&&... rest) {
return compose( compose(std::forward<A>(a), std::forward<B>(b)), std::forward<Rest>(rest)... );
}
template<class A>
std::decay_t<A> compose(A&& a) {
return std::forward<A>(a);
}
in C++14. Now, this isn't perfect, as the pattern doesn't work all that well in C++.
To do this perfectly, we'd have to take a look at compositional programming. Here, functions interact with an abstract stack of arguments. Each function pops some number of arguments off the stack, then pops some number back on.
This would allow you do do this:
compose( print_coord, get_x, get_y )
where get_x and get_y consume nothing but return a coordinate, and print_coord takes two coordinates and prints them.
To emulate this in C++, we need some fancy machinery. Functions will return tuples (or tuple-likes?), and those values will be "pushed onto the argument stack" logically.
Functions will also consume things off this argument stack.
At each invocation, we unpack the current tuple of arguments, find the longest collection that the function can be called with, call it, get its return value, unpack it if it is a tuple, and then stick any such returned values back on the argument stack.
For this more advanced compose to compose with itself, it then needs SFINAE checks, and it needs to be able to take a invokable object and a tuple of arguments and find the right number of arguments to call the invokable object with, plus the left-over arguments.
This is a tricky bit of metaprogramming that I won't do here.
The second part, because I missed it the first time, looks like:
template<class F>
auto function_to_the_power( F&& f, unsigned count ) {
return [f=std::forward<F>(f),count](auto&& x)
-> std::decay_t< decltype( f(decltype(x)(x)) ) >
{
if (count == 0) return decltype(x)(x);
auto r = f(decltype(x)(x));
for (unsigned i = 1; i < count; ++i) {
r = f( std::move(r) );
}
return r;
};
}
This uses no type erasure.
Test code:
auto f = [](int x){ return x*3; };
auto fs = std::make_tuple(
function_to_the_power( f, 0 ),
function_to_the_power( f, 1 ),
function_to_the_power( f, 2 ),
function_to_the_power( f, 3 )
);
std::cout << std::get<0>(fs)(2) << "\n";
std::cout << std::get<1>(fs)(2) << "\n";
std::cout << std::get<2>(fs)(2) << "\n";
std::cout << std::get<3>(fs)(2) << "\n";
prints:
2
6
18
54
You can write something along the lines of:
#include <functional>
#include <iostream>
template<class F>
F compose(F f, F g)
{
return [=](int x) { return f(g(x)); };
}
int main()
{
std::function<int (int)> f = [](int i) { return i * 2; };
std::function<int (int)> g = [](int i) { return i + 10; };
auto c = compose(f, g);
std::cout << c(20) << '\n'; // prints 60
}
The code can be simply extended to cover the second half of the question:
template<class F>
F compose(F f, unsigned n)
{
auto g = f;
for (unsigned i = 0; i < n; ++i)
g = compose(g, f);
return g;
}
int main()
{
std::function<int (int)> h = [](int i) { return i * i; };
auto d = compose(h, 1);
auto e = compose(h, 2);
std::cout << d(3) << "\n" // prints 81
<< e(3) << "\n"; // prints 6561
}
NOTE. Here using std::function. It isn't a lambda but wraps a lambda with a performance cost.

How to iterate over entire range /wo overflow of counter?

How to execute the body of the loop for every member of some type? I know I could repeat the body of the loop for the maxval after the loop, but it would be duplicating code which is bad. I also could make a function out of the body but it looks wrong to me too because functions should be small and simple and the body of the loop is huge.
const auto minval = std::numeric_limits<T>::min();
const auto maxval = std::numeric_limits<T>::max();
for (auto i = minval; i < maxval; ++i) {
// huge body of the loop
}
It is as simple as stopping after you process the last item:
auto i = minval;
while(1) {
// do all the work for `i`
if (i == maxval) break;
++i;
}
One can also move the increment to the top of the loop, provided it is skipped on the first pass:
i = minval;
switch (1) {
case 0:
do {
++i;
case 1:
// processing for `i`
} while (i != maxval);
}
The latter version translates to efficient machine code a little more directly, as each loop iteration has only a single conditional branch, and there is a single unconditional branch, while in the first there is a conditional branch plus an unconditional branch which both repeat every iteration.
Neither version increments the ultimate value, which might be undefined behavior.
You have to maintain a bit of additional state to indicate whether you've seen the last value or not. Here's a simple example that could be moved to a more idiomatic iterator style without too much work:
#include <iostream>
#include <limits>
using namespace std;
template <typename T>
class allvalues
{
public:
allvalues() = default;
T next()
{
if (done) throw std::runtime_error("Attempt to go beyond end of range");
T v = val;
done = v == std::numeric_limits<T>::max();
if (!done) ++val;
return v;
}
bool isDone() { return done; }
private:
T val = std::numeric_limits<T>::min();
bool done = false;
};
int main() {
allvalues<char> range;
while (!range.isDone())
{
std::cout << "Value = " << (int)range.next() << std::endl;
}
allvalues<unsigned char> urange;
while (!urange.isDone())
{
std::cout << "Value = " << (unsigned int)urange.next() << std::endl;
}
std::cout << "That's it!" << std::endl;
}

Resources