#include <iostream>
using namespace std;

struct MultiCallToken
{
private:
	bool inUse = false;
	
	friend class MultiCallGuard;
};

// guards against multiple calls
class MultiCallGuard
{
public:
	~MultiCallGuard()
	{
		if(token && free)
		{
			token->inUse = false;
		}
	}
	
	operator bool()
	{
		if(token->inUse)
			return false;
			
		return token->inUse = free = true;
	}
	
	MultiCallGuard(const MultiCallGuard&) = delete;
	MultiCallGuard& operator=(const MultiCallGuard&) = delete;
	MultiCallGuard(MultiCallGuard&& g) : token(g.token), free(g.free)
	{
		g.token = nullptr;
	}
	
	MultiCallGuard& operator=(MultiCallGuard&& g)
	{
		token = g.token;
		free = g.free;
		g.token = nullptr;
	}
	
private:
	MultiCallGuard(MultiCallToken& token) : token(&token), free(false) {}

	MultiCallToken* token;
	bool free;
	
	friend MultiCallGuard guard(MultiCallToken&);
};

MultiCallGuard guard(MultiCallToken& t)
{
	MultiCallGuard g(t);
	return g;
}

MultiCallToken fooToken;
MultiCallToken barToken;

void bar();

void foo()
{
	if(auto g = guard(fooToken))
	{
		cout << "foo called\n";
		
		bar();
	}
}

void bar()
{
	if(auto g = guard(barToken))
	{
		cout << "bar called\n";
		
		foo();
	}
}

int main()
{
	cout << ">> explicit call to foo:\n";
	
	foo();

	cout << "\n>> explicit call to bar\n";

	bar();

	return 0;
}