Skip to content

Instantly share code, notes, and snippets.

@dpzmick
Created May 21, 2017 05:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dpzmick/ed2a1cd578c80669eeeada8b7be86881 to your computer and use it in GitHub Desktop.
Save dpzmick/ed2a1cd578c80669eeeada8b7be86881 to your computer and use it in GitHub Desktop.
#include "typestring.hh"
#include <memory>
#include <thread>
#include <type_traits>
#include <iostream>
// by default nothing is realtime
template <typename T>
struct RTSaftey
{
static constexpr bool is_rt = false;
};
// elevate a function to realtime
// this uses the name passed in directly, so it will never work on class members
// unless you can get __PRETTY_FUNC__ without being inside of the function
#define REALTIME(fname) \
template <> \
struct RTSaftey<typestring_is(#fname)> \
{ static constexpr bool is_rt = true; }; \
// mark a function as being not safe for realtime execution. If a function
// realtime safe, but also isn't annotated with this function, no checks will be
// performed.
#define NOT_REALTIME_SAFE(fname, helper_name) \
template <> \
struct RTSaftey<typestring_is(#fname)> \
{ static constexpr bool is_rt = false; }; \
\
struct fname##__STRUCT { \
template<bool caller_is_rt, typename... Args> \
auto call(Args... args) -> decltype(helper_name(args...)) \
{ \
static_assert(!caller_is_rt, "cannot call non-realtime from realtime function"); \
return helper_name(args...); \
} \
};
// generates a macro which will call a function that has been decorated with
// NOT_REALTIME_SAFE
#define MAKE_FN(name, ...) name##__STRUCT{}.call< \
RTSaftey<typestring_is(__func__)>::is_rt>(__VA_ARGS__)
// define two templated functions which check if the input has a default value
// these do not have to be forward declared, but a forward declaration will
// allow us to be slightly more order agnostic
template <typename T> bool not_safe_helper(T test);
template <typename T> bool safe(T test);
// create a wrapper struct for `not_safe_helper`, then create a macro which will
// invoke the `call` method of the wrapper struct
// if nothing is ever decorated with NOT_REALTIME_SAFE, no checks are performed
// (so this is also pretty broken)
NOT_REALTIME_SAFE(not_safe, not_safe_helper);
#define not_safe(...) MAKE_FN(not_safe, __VA_ARGS__)
// declare `safe` as a realtime function
// this can't work on class member functions, but templated functions are okay
// (as long as realtime safety doesn't depend on the template parameters)
REALTIME(safe)
// finally, provide implementations for these functions
template <typename T>
bool not_safe_helper(T test)
{
if (test == T{}) return true;
return false;
}
template<typename T>
bool safe(T test)
{
return not_safe(0); // this causes a compiler
// return false;
}
int main()
{
safe(100);
return not_safe(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment