Is it possible to change behavior of function based on scope? - c++

I would like to create something similar to rust unsafe scope in C++.
The idea is that I have some functions performing number of checks. For example:
void check() {
if (...)
throw exception(...);
}
void foo() {
check();
// do some work
}
Now, I want to be able to call function foo() with or (in different context) without performing those checks. Ideally it would look like this:
foo(); // call foo and perform checks
unsafe {
foo(); // call foo without checks
}
My question is, is it possible to achieve something like this in compile time? Is it possible to somehow check (or act differently) from check function in what scope it is called?
I came up only with a runtime solution: to wrap it in some lambda:
unsafe([&] {
foo();
});
where unsafe is implemented as follows:
void unsafe(std::function<void()> f)
{
thread_local_flag = unsafe;
f();
thread_local_flag = safe;
}
check() function would just check for the thread_local flag and perform checks only when it is set to safe.

🤔
namespace detail_unsafe {
thread_local int current_depth;
struct unsafe_guard {
unsafe_guard() { ++current_depth; }
~unsafe_guard() { --current_depth; }
unsafe_guard(unsafe_guard const &) = delete;
unsafe_guard &operator = (unsafe_guard const &) = delete;
};
}
#define unsafe \
if(::detail_unsafe::unsafe_guard _ug; false) {} else
bool currently_unsafe() {
return detail_unsafe::current_depth > 0;
}
See it live on Coliru. Also, please don't actually define unsafe as a macro...

is it possible to achieve something like this in compile time?
Not the way you presented. Making foo a template function might give you equivalent results, though:
enum class CallType // find a better name yourself...
{
SAFE,
UNSAFE,
};
template <CallType Type = CallType::SAFE>
void foo()
{
if constexpr(Type != CallType::UNSAFE)
{
if (...)
throw ...;
}
// do some work
}
You might call it like:
foo();
foo<CallType::UNSAFE>();
Disliking templates?
Simple approach (thanks, #VTT):
void check(); // no template any more
void foo_unsafe()
{
// do some work
}
inline void foo()
{
check();
foo_unsafe();
}
Or selecting via parameter (this pattern exists in standard library, too):
struct Unsafe
{
};
inline Unsafe unsafe;
void check();
void foo(Unsafe)
{
// do some work
}
inline void foo()
{
check();
foo(unsafe);
}
Edit:
Well, in the example I presented I could do that, but in general, I can call some other function bar inside unsafe which in turn calls foo. And I don't want to specialize bar and possible other methods.
Unter this constraint, the template variant might be the closest you can get to at compile time; you don't have to specialise all the functions, but you'd need to make templates from:
template <CallType Type = CallType::SAFE>
void bar()
{
// do some other work
foo<Type>(); // just call with template parameter
// yet some further work
}

I would simply use a RAII type to toggle the unsafe flag inside a scope as such:
thread_local bool unsafe_flag = false;
/// RAII Type that toggles the flag on while it's alive
/// Possibly add a reference counter so it can be used nested
struct unsafe_scope
{
constexpr unsafe_scope() { unsafe_flag = true; }
~unsafe_scope() { unsafe_flag = false; }
};
/// Gets a value from a pointer
int get_value(int* ptr)
{
if ( unsafe_flag )
{
if ( ptr == nullptr ) { return 0; }
}
return *ptr;
}
int main()
{
int* x = nullptr;
//return get_value(x); // Doesn't perform the check
{
unsafe_scope cur_scope;
return get_value(x); // Performs the check
}
}
In order to make it nested I would add a reference counter like this:
/// RAII Type that toggles the flag on while it's alive
struct unsafe_scope
{
thread_local static size_t ref_count;
constexpr unsafe_scope()
{
unsafe_flag = true;
ref_count++;
}
~unsafe_scope()
{
ref_count--;
if ( ref_count == 0 ) { unsafe_flag = false; }
}
};
/// In source file
thread_local size_t unsafe_scope::ref_count = 0;
The ref_count doesn't need to be atomic since it's thread_local
Now I don't think there's a way to achieve the syntax you wanted with the unsafe before the scope, but if you put it right after the scope as such it should be about the same:
{ unsafe_scope cur_scope;
return get_value(x); // Performs the check
}
Edit:
I've now noticed Quentin's answer is also a RAII type, just with slightly different semantics, instead of having a global thread_local flag a function just returns if the reference counter is bigger than 0. Also the macro achieves the exact syntax you wanted, although it's also possible with this unsafe_scope by modifying his macro like this:
#define unsafe\
if (unsafe_scope cur_scope; false) {} else
His method uses C++17's if initializer, which lets you initiates a variable in the if statement, but the variable is still initialized in the else block, so it only gets destroyed after the else scope if over.

Related

How to design a class method can only be invoked once

I have stateful class, once a class instance is created, its Bar function/method can only be called once otherwise the internal state will mess up. How to design such thing?
Something can warn/error at compile time would be better.
class Foo {
bool Bar(string arg...) { do something...}
// some class member
string s;
int i;
}
You could define a static flag inside Foo::Bar() that keeps track of whether or not the function has already been called:
bool Foo::Bar() {
static bool has_been_called; // initialized to false
if (!has_been_called) {
has_been_called = true
// ...
// do something
// ...
return true;
}
return false;
}
For the case that multiple threads may call the member function, you can
use std::call_once() instead; as the read of the flag has_been_called above is not synchronized with the write.
bool Bar() {
static std::once_flag flag;
bool executed = false;
std::call_once(flag, [this, &executed]() {
// ...
// do something
// ...
executed = true;
});
return executed;
}

Clean way to lazy initialize and cache internal value in lambda

Let the code speak for itself first with naive approach:
int heavy_calc() // needed to be called once
{
// sleep(7500000 years)
return 42;
}
int main()
{
auto foo = [] {
// And cached for lambda return value
static int cache = heavy_calc();
return cache;
};
return foo() + foo();
}
I want to have lambda internal cached value calculated on the first call. An naive approach is to use static cache, but it increases binary size and refuses to be be inlined.
I came up with creating cache in capture list and marking lambda as mutable, what inlines without problems, but requires cache to start with default value, which may break class invariant.
auto foo = [cache=0] () mutable {
// And cached for lambda return value
if(!cache)
cache = heavy_calc();
return cache;
};
My third approach uses boost::optional in mutable lambda
auto foo = [cache=std::optional<int>{}] () mutable {
// And cached for lambda return value
if(!cache)
cache = heavy_calc();
return *cache;
};
It works properly, but looks for me as kind of capture list + mutable keyword hack. Also mutable affects all captured parameters, so makes lambda less safe in real use.
Maybe there is an better/more clean solution for this? Or just different approach which ends up with the very same effect.
EDIT, some background:
Lambda approach is chosen as I am modifying some callback lambda, which currently is used as:
[this, param]{this->onEvent(heavy_calc(param));}
I want to reduce heavy_calc calls without evaluating it in advance (only on first call)
To be honest, I don't see any reason to use lambda here. You can write a regular reusable class to cache calculation value. If you insist on using lambda then you can move value calculation to parameters so there will be no need to make anything mutable:
int heavy_calc() // needed to be called once
{
// sleep(7500000 years)
return 42;
}
int main()
{
auto foo
{
[cache = heavy_calc()](void)
{
return cache;
}
};
return foo() + foo();
}
online compiler
With a bit of template it is possible to write a class that will lazy evaluate and cache result of arbitrary calculation:
#include <boost/optional.hpp>
#include <utility>
template<typename x_Action> class
t_LazyCached final
{
private: x_Action m_action;
private: ::boost::optional<decltype(::std::declval<x_Action>()())> m_cache;
public: template<typename xx_Action> explicit
t_LazyCached(xx_Action && action): m_action{::std::forward<xx_Action>(action)}, m_cache{} {}
public: auto const &
operator ()(void)
{
if(not m_cache)
{
m_cache = m_action();
}
return m_cache.value();
}
};
template<typename x_Action> auto
Make_LazyCached(x_Action && action)
{
return t_LazyCached<x_Action>{::std::forward<x_Action>(action)};
}
class t_Obj
{
public: int heavy_calc(int param) // needed to be called once
{
// sleep(7500000 years)
return 42 + param;
}
};
int main()
{
t_Obj obj{};
int param{3};
auto foo{Make_LazyCached([&](void){ return obj.heavy_calc(param); })};
return foo() + foo();
}
online compiler
It works properly, but looks for me as kind of capture list + mutable keyword hack. Also mutable affects all captured parameters, so makes lambda less safe in real use.
There is the solution to roll your own, hand-made lambda:
#include <optional>
int heavy_calc() // needed to be called once
{
// sleep(7500000 years)
return 42;
}
int main()
{
struct {
std::optional<int> cache;
int operator()() {
if (!cache) cache = heavy_calc();
return *cache;
}
} foo;
return foo() + foo();
}
It's inlined the same way and you don't need to rely on the capture+mutable hack.
I do believe this is exactly the use case for mutable lambda. If you don't want to have all variables mutable I suggest just creating functor class with one mutable field. This way you get best of both worlds (ok, it isn't that concise). The additional benefit is that the operator() is const (which is quite right, as it always returns same value)
#include <optional>
int heavy_calc() {
// sleep(7500000 years)
return 42;
}
struct my_functor {
mutable std::optional<int> cache;
int operator()() const {
if (!cache) cache = heavy_calc();
return *cache;
}
}
int main() {
my_functor foo;
return foo() + foo();
}

Static statements inside a function [duplicate]

I have an application which has several functions in it. Each function can be called many times based on user input. However I need to execute a small segment of the code within a function only once, initially when the application is launched. When this same function is called again at a later point of time, this particular piece of code must not be executed. The code is in VC++. Please tell me the most efficient way of handling this.
Compact version using lambda function:
void foo()
{
static bool once = [](){
cout << "once" << endl;
return true;
} ();
cout << "foo" << endl;
}
Code within lambda function is executed only once, when the static variable is initialized to the return value of lambda function. It should be thread-safe as long as your compiler support thread-safe static initialization.
Using C++11 -- use the std::call_once
#include <mutex>
std::once_flag onceFlag;
{
....
std::call_once ( onceFlag, [ ]{ /* my code body here runs only once */ } );
....
}
Use global static objects with constructors (which are called before main)? Or just inside a routine
static bool initialized;
if (!initialized) {
initialized = true;
// do the initialization part
}
There are very few cases when this is not fast enough!
addenda
In multithreaded context this might not be enough:
You may also be interested in pthread_once or constructor function __attribute__ of GCC.
With C++11, you may want std::call_once.
You may want to use <atomic> and perhaps declare static volatile std::atomic_bool initialized; (but you need to be careful) if your function can be called from several threads.
But these might not be available on your system; they are available on Linux!
You can use local static variable:
void foo()
{
static bool wasExecuted = false;
if (wasExecuted)
return;
wasExecuted = true;
...
}
Additionally to #Basile's answer, you can use a lambda to encapsulate the static variable as follows:
if ([] {
static bool is_first_time = true;
auto was_first_time = is_first_time;
is_first_time = false;
return was_first_time; } ())
{
// do the initialization part
}
This makes it easy to convert into a general-purpose macro:
#define FIRST_TIME_HERE ([] { \
static bool is_first_time = true; \
auto was_first_time = is_first_time; \
is_first_time = false; \
return was_first_time; } ())
Which can be placed anywhere you want call-by-need:
if (FIRST_TIME_HERE) {
// do the initialization part
}
And for good measure, atomics shorten the expression and make it thread-safe:
#include <atomic>
#define FIRST_TIME_HERE ([] { \
static std::atomic<bool> first_time(true); \
return first_time.exchange(false); } ())
could you do this
have a function that return a bool or some datatype called init
I made it happen this way, you need static bool to make it happens
bool init()
{
cout << "Once " <<endl;
return true||false;// value isn't matter
}
void functionCall()
{
static bool somebool = init(); // this line get executed once
cout << "process " <<endl;
}
int main(int argc, char *argv[])
{
functionCall();
functionCall();
functionCall();
return EXIT_SUCCESS;
}
for C
#include <stdio.h>
void init()
{
printf("init\n");
}
void process()
{
static int someint = 0;
if(someint == 0)
{
someint = 1;
init();
}
printf("process\n");
}
int main()
{
process();
process();
process();
return 0;
}
std::call_once() et al. may be overkill if you don't need a totally thread-safe solution.
If not, we can make this look especially elegant when using C++17's initialisation-within-if and std::exchange():
#include <utility>
void
do_something_expensive_once()
{
if ( static auto called = false; !std::exchange(called, true) ) {
do_something_expensive();
}
}
If this is a pattern you use a lot, then we can encapsulate it via a tag type:
#include <iostream>
#include <utility>
template <typename T>
auto
call_once()
{
static auto called = false;
return !std::exchange(called, true);
}
void
do_something_expensive()
{
std::cout << "something expensive\n";
}
void
do_something_expensive_once()
{
if ( call_once<struct TagForSomethingExpensive>() ) {
do_something_expensive();
}
}
auto
main() -> int
{
for (auto i = 0; i < 5; ++i) {
do_something_expensive_once();
}
return 0;
}
This will only print something expensive a single time. Result! It also uses the ability to declare a tag struct in a template argument list, for maximal brevity.
Alternatively, you could template on a function's address, a unique integer, etc.
You can then also pass a callable to call_once(), and so on, and so forth. As usual for C++: the possibilities are endless!
With due respect to std::call_once() and the usual caveats about thread safety, here's another lightweight option which avoids unused variable warnings and keeps our flag in block scope:
for (static bool once=true; once; once=false) {
yourCodeHere();
}
Another simple solution is:
#define execute_once if(static bool b = false; b) ; else if((b = true))
Used thus:
execute_once std::cout << "Hi mum!\n";
or:
execute_once
{
std::cout << "These statements are ";
std::cout << "only executed once\n";
}
It's not thread safe, obviously. (EDIT: although just using a std::atomic_bool in place of the bool would get you there I think.)
do {
//execute code once
} while (false)

c++ how to define constant function order that needs to be invoked for other developers

The problem i have that i have several functions that needs to be invoked in defined order the order can't be breakable.
now the code need to be continued and develop after i finish to code.
im looking for some method to set the functions in some kind of unbreakable structure.
for example i have:
function_1() { //do some stuff ..} ; // must be first
function_2() { //do some stuff based on function_1()..}; // must be second
function_3() { //do some stuff based on function_1() and function_2()..};; // must be third
they all under the main() app function .
Create another function for public access, that guarantees the other three functions are called in the correct order. To prevent those functions are visible with the public API, you can hide them in an unnamed namespace.
In your header put
bool function_4();
In your corresponding translation unit you create an unnamed namespace to prevent others from seeing those functions
namespace {
bool function_1() {
}
bool function_2() {
}
bool function_3() {
}
}
And define function_4
bool function_4() {
return function_1() &&
function_2() &&
function_3();
}
I suppose that you have some solid reasons not to wrap all these three functions into one single function.
In this case the simplest approach, would be to manage a status that is shared between all the three functions:
static int function_status=0; // shared status: nothing was called
function_1() {
if (status>0)
throw exception ("function_1 MUST be called first and only once");
status=1; // function_1 was called
...
}
function_2() {
if (status<1)
throw exception ("function_1 MUST be called before 2");
else if (status>2) // I suppose function 2 could be called several times
throw exception ("function_2 CANNOT be called after 3");
status = 2;
...
}
function_3() {
if (status<2)
throw exception ("function_2 MUST be called before 3");
else if (status==3)
throw exception ("function_3 CAN ONLY BE CALLED ONCE");
status = 3;
...
}
As you see, this status gives you the opportunity to check very precisely if the flow of execution respects the logic that you want.
You can create a wrapping function
bool execute()
{
return function_1() && function_2() && function_3();
}
The functions will be called in order, and it will short circuit if any of the functions fail. Assuming the functions return a bool indicating success/failure, if the function returns true all functions successfully completed, otherwise at least one of them failed.
The simple case of ordering functions is to make a single function that is called by the user, that does all three of the subfunctions. However, this doesn't always work. The user may need to do some processing after function1 before calling function2. In that case, you need some kind of extra context, e.g.
class Context
{
friend Function1, Function2, Function3;
enum State
{
f0, f1, f2, f3
} state;
public:
Context() { state = f0; }
~Context() { if (state != f3) { ... may need to do stuff... }
}
void Function1(Context &ctxt)
{
assert(ctxt.state == f0);
ctxt.state = f1;
...
}
void Function2(Context &ctxt)
{
assert(ctxt.state == f1);
ctxt.state = f2;
...
}
void Function3(Context &ctxt)
{
assert(ctxt.state == f2);
ctxt.state = f3;
...
}
int main()
{
Context c;
Function1(c);
...
Function2(c);
...
Function3(c);
// c will be destroyed and check that state is f3.
}
One hack you can try is to have function_1() return a type that only it can construct and then use this as a parameter to function_2()
class created_by_function_1 {
created_by_function_1() { /* private constructor */ }
friend created_by_function_1 function_1();
};
created_by_function_1 function_1() {
// do stuff
return created_by_function_1();
}
void function_2(created_by_function_1) {
}
Now you can only use function_2 if you first called function_1.
auto proof = function_1();
function_2(proof); // OK
function_2(created_by_function_1()); // Compilation error
I would advise against using this :)

How to execute a piece of code only once?

I have an application which has several functions in it. Each function can be called many times based on user input. However I need to execute a small segment of the code within a function only once, initially when the application is launched. When this same function is called again at a later point of time, this particular piece of code must not be executed. The code is in VC++. Please tell me the most efficient way of handling this.
Compact version using lambda function:
void foo()
{
static bool once = [](){
cout << "once" << endl;
return true;
} ();
cout << "foo" << endl;
}
Code within lambda function is executed only once, when the static variable is initialized to the return value of lambda function. It should be thread-safe as long as your compiler support thread-safe static initialization.
Using C++11 -- use the std::call_once
#include <mutex>
std::once_flag onceFlag;
{
....
std::call_once ( onceFlag, [ ]{ /* my code body here runs only once */ } );
....
}
Use global static objects with constructors (which are called before main)? Or just inside a routine
static bool initialized;
if (!initialized) {
initialized = true;
// do the initialization part
}
There are very few cases when this is not fast enough!
addenda
In multithreaded context this might not be enough:
You may also be interested in pthread_once or constructor function __attribute__ of GCC.
With C++11, you may want std::call_once.
You may want to use <atomic> and perhaps declare static volatile std::atomic_bool initialized; (but you need to be careful) if your function can be called from several threads.
But these might not be available on your system; they are available on Linux!
You can use local static variable:
void foo()
{
static bool wasExecuted = false;
if (wasExecuted)
return;
wasExecuted = true;
...
}
Additionally to #Basile's answer, you can use a lambda to encapsulate the static variable as follows:
if ([] {
static bool is_first_time = true;
auto was_first_time = is_first_time;
is_first_time = false;
return was_first_time; } ())
{
// do the initialization part
}
This makes it easy to convert into a general-purpose macro:
#define FIRST_TIME_HERE ([] { \
static bool is_first_time = true; \
auto was_first_time = is_first_time; \
is_first_time = false; \
return was_first_time; } ())
Which can be placed anywhere you want call-by-need:
if (FIRST_TIME_HERE) {
// do the initialization part
}
And for good measure, atomics shorten the expression and make it thread-safe:
#include <atomic>
#define FIRST_TIME_HERE ([] { \
static std::atomic<bool> first_time(true); \
return first_time.exchange(false); } ())
could you do this
have a function that return a bool or some datatype called init
I made it happen this way, you need static bool to make it happens
bool init()
{
cout << "Once " <<endl;
return true||false;// value isn't matter
}
void functionCall()
{
static bool somebool = init(); // this line get executed once
cout << "process " <<endl;
}
int main(int argc, char *argv[])
{
functionCall();
functionCall();
functionCall();
return EXIT_SUCCESS;
}
for C
#include <stdio.h>
void init()
{
printf("init\n");
}
void process()
{
static int someint = 0;
if(someint == 0)
{
someint = 1;
init();
}
printf("process\n");
}
int main()
{
process();
process();
process();
return 0;
}
std::call_once() et al. may be overkill if you don't need a totally thread-safe solution.
If not, we can make this look especially elegant when using C++17's initialisation-within-if and std::exchange():
#include <utility>
void
do_something_expensive_once()
{
if ( static auto called = false; !std::exchange(called, true) ) {
do_something_expensive();
}
}
If this is a pattern you use a lot, then we can encapsulate it via a tag type:
#include <iostream>
#include <utility>
template <typename T>
auto
call_once()
{
static auto called = false;
return !std::exchange(called, true);
}
void
do_something_expensive()
{
std::cout << "something expensive\n";
}
void
do_something_expensive_once()
{
if ( call_once<struct TagForSomethingExpensive>() ) {
do_something_expensive();
}
}
auto
main() -> int
{
for (auto i = 0; i < 5; ++i) {
do_something_expensive_once();
}
return 0;
}
This will only print something expensive a single time. Result! It also uses the ability to declare a tag struct in a template argument list, for maximal brevity.
Alternatively, you could template on a function's address, a unique integer, etc.
You can then also pass a callable to call_once(), and so on, and so forth. As usual for C++: the possibilities are endless!
With due respect to std::call_once() and the usual caveats about thread safety, here's another lightweight option which avoids unused variable warnings and keeps our flag in block scope:
for (static bool once=true; once; once=false) {
yourCodeHere();
}
Another simple solution is:
#define execute_once if(static bool b = false; b) ; else if((b = true))
Used thus:
execute_once std::cout << "Hi mum!\n";
or:
execute_once
{
std::cout << "These statements are ";
std::cout << "only executed once\n";
}
It's not thread safe, obviously. (EDIT: although just using a std::atomic_bool in place of the bool would get you there I think.)
do {
//execute code once
} while (false)