Check if class member is static - templates

I have code like this and I want to check in my template (using a static if), if C.foo and C.bar are static or not:
class C {
int foo;
static int bar;
}
I tried these traits already but they don't seem to change for static members:
pragma(msg, __traits(hasMember, C, "foo")); // -> true
pragma(msg, __traits(hasMember, C.init, "foo")); // -> true
pragma(msg, __traits(hasMember, C, "bar")); // -> true
pragma(msg, __traits(hasMember, C.init, "bar")); // -> true
This hack which actually works for structs doesn't work for classes either:
pragma(msg, __traits(compiles, { enum tmp = __traits(getMember, C, "foo"); })); // -> false
pragma(msg, __traits(compiles, { enum tmp = __traits(getMember, C.init, "foo"); })); // -> false
pragma(msg, __traits(compiles, { enum tmp = __traits(getMember, C, "bar"); })); // -> false
pragma(msg, __traits(compiles, { enum tmp = __traits(getMember, C.init, "bar"); })); // -> false

The trick is that static member variables do not have an offsetof property. So, you can do something like
template isStaticMember(T, string memberName)
if(__traits(hasMember, T, memberName))
{
mixin("alias member = " ~ T.stringof ~ "." ~ memberName ~ ";");
enum isStaticMember = !__traits(compiles, member.offsetof);
}
class C
{
int foo;
static int bar;
}
void main()
{
static assert(!isStaticMember!(C, "foo"));
static assert(isStaticMember!(C, "bar"));
}
There probably should be something in std.traits for this, but there isn't yet.

Related

Rust generics: list where each element is from the same trait?

I found this question on the Rust users forum : Generics: Can I say "tuple where each element is FromSql". Basically, the questions was to know how do something like that :
trait Foo {}
struct A {}
impl Foo for A {}
struct B {}
impl Foo for B {}
fn main() {
let x = (A{}, A{}, B{}, A{});
bar(x);
}
fn bar<T: Foo>(tuple: (T...)) {
}
This code does not work, it's an idea of how it could look like.
So, how can we do that?
The first step is to create a ToAny trait that will be implemented for all our structures.
use std::any::Any;
pub trait ToAny {
fn as_any(&self) -> &dyn Any;
}
Let's create our trait
trait Foo: ToAny {}
It requires implementing the ToAny trait to force each structure implementing Foo to implement ToAny too.
Let's create our structures:
struct A {
id: i32,
}
impl ToAny for A {
fn as_any(&self) -> &dyn Any {
self
}
}
impl Foo for A {}
struct B {
id: i32,
}
impl ToAny for B {
fn as_any(&self) -> &dyn Any {
self
}
}
impl Foo for B {}
The implementation of ToAny is always the same, we could create a macro implementing it easily.
And then, we can create a Vec instead of a tuple to store our values:
let boxeds: Vec<Box<dyn A>> = vec![
Box::new(A {id: 1}),
Box::new(B {id: 2}),
Box::new(A {id: 3}),
Box::new(B {id: 4}),
];
// Stores the values being `B`.
let mut bees: Vec<&B> = vec![];
for boxed in &boxeds {
// `Some(x)` if `boxed` contains a `B` value.
let found = match boxed.as_any().downcast_ref::<B>() {
Some(b) => b,
None => {}, // it is a `A` value.
};
bees.push(found);
}
assert_eq!(bees, vec![
&B {id: 2},
&B {id: 4}
]);
If we refer to the question, the following code:
fn bar<T: Foo>(tuple: (T...)) {
}
can be this valid code:
fn bar(values: Vec<Box<dyn Foo>>) {
}
I've written a gist file being tests for that. Be careful, I've changed the names in this post, Foo is A and there is only the B structure.
Use a macro to implement Foo for tuples:
trait Foo {
fn do_it(&self);
}
struct A {}
impl Foo for A {
fn do_it(&self) {
print!("A");
}
}
struct B {}
impl Foo for B {
fn do_it(&self) {
print!("B");
}
}
fn main() {
let x = (A{}, A{}, B{}, A{});
bar(x);
}
fn bar<T: Foo>(tuple: T) {
tuple.do_it();
}
macro_rules! impl_Foo_for_tuple {
( $first:ident $($rest:ident)* ) => {
impl< $first: Foo, $( $rest : Foo, )* > Foo for ( $first, $($rest,)* ) {
fn do_it(&self) {
#[allow(non_snake_case)]
let ( $first, $($rest,)* ) = self;
$first.do_it();
$( $rest.do_it(); )*
}
}
impl_Foo_for_tuple!( $($rest)* );
};
() => {};
}
impl_Foo_for_tuple!(A B C D E F G H I J K L M);

Is there an EASY way to simulate local functions?

I've got a member-function that need to access both member data and "local" data:
struct S final
{
int i = 123;
// ... a bunch of legacy code ...
void f()
{
// ... a bunch of legacy code ...
double d = 1.23;
// ... a bunch of legacy code ...
g(d);
// ... a bunch of legacy code ...
}
// ... a bunch of legacy code ...
void g(double& d)
{
i = 456; d = 4.56;
}
};
This, of course, works ... however, it becomes a nuisance as more variables local to f() are passed to g(). Is there an 'easy' way to avoid this?
Using a lambda is the "stock" answer, however that means the code for g() must be moved to be part of f(); I don't want to do that:
struct S final
{
int i = 123;
void f()
{
double d = 1.23;
auto g = [&]() { i = 456; d = 4.56; } // code moved here :-(
g(d);
}
};
Something like this is close (although the lambda is "better" as local variables are part of the closure with [&]), but it's not valid C++
struct S final
{
int i = 123;
void f()
{
double d = 1.23;
void g();
g();
}
void f::g()
{
i = 456; d = 4.56;
}
};
Or (again, using fictional syntax) a way to declare a lambda and then define it later:
struct S final
{
int i = 123;
void f()
{
double d = 1.23;
auto g = [&]();
g();
g = { i = 456; d = 4.56; }
}
};
Just put them in a struct
struct S final
{
struct g_params { //that's it
double d;
};
int i = 123;
void f()
{
g_params d = {1.23};
g(d);
// ... assume this is already a large function ...
}
// ... lots of code here ...
void g(g_params& p)
{
i = 456; p.d = 4.56;
}
};

Why is type checking not happening for std::function?

#include <functional>
void toggleOk(bool& b) { b = !b; }
void toggleBroken(bool b) { b = !b; }
void toggleInt(int i) { i = !i; }
void tooManyParams(bool b, int i) { i = !b; }
int main()
{
typedef std::function<void(bool&)> CallbackType;
typedef std::function<void(bool)> WrongCallbackType;
CallbackType cb1 = [](bool b) { b = !b; }; // Should throw error - missing reference
CallbackType cb2 = toggleOk; // Ok
CallbackType cb3 = toggleBroken; // Should throw error - missing reference
CallbackType cb4 = toggleInt; // Should throw error - integer instead of bool
WrongCallbackType cb5 = toggleBroken; // Ok
CallbackType cb6 = cb5; // Type checking not even applying between std::functions
CallbackType cb7 = tooManyParams; // Only this statement throws error
return 0;
}
Consider the above example, which is creating a bunch of callbacks that have reference to bool as a parameter. Except the very last callback cb7, this code can compile and run just fine, even though most of the functions stored in the callback objects mismatch the reference or type of the parameter.
I've encountered this behavior with VS19/C++20 with the lambda stored in the std::function, however I've tried this example with two distinct G++ compilers for Windows, with extra diagnostics enabled and with C++17/C++2a and none reported even a warning.
My question is - is this an expected behavior or is it a bug? Why?
Yes, this is defined behavior from std::function
The std::function uses a type erasure mechanism to warp almost all kinds of callable objects, and parameterized to the non-const, non-ref non-volatile arguments and the return type of the callable.
You need to use plane typed function pointer to get the expected errors in the code
void toggleOk(bool& b) { b = !b; }
void toggleBroken(bool b) { b = !b; }
void toggleInt(int i) { i = !i; }
void tooManyParams(bool b, int i) { i = !b; }
int main()
{
// typedef std::function<void(bool&)> CallbackType;
// typedef std::function<void(bool)> WrongCallbackType;
using CallbackType = void(*)(bool&);
using WrongCallbackType = void(*)(bool);
CallbackType cb1 = [](bool b) { b = !b; }; // error
CallbackType cb2 = toggleOk; // Ok
CallbackType cb3 = toggleBroken; // error
CallbackType cb4 = toggleInt; // error
WrongCallbackType cb5 = toggleBroken; // Ok
CallbackType cb6 = cb5; // error
return 0;
}
Now in the above CallbackType and WrongCallbackType are different types, and will produce the error as you expected.
However, you can only use the function pointer type (as shown above) in the case of lambda, only if it is stateless (do not capture anything).

nullptr can't be detected by is.null in R

I Used RCPP_MODULE to wrap following class.
struct Dummy
{
};
struct Test
{
Dummy* get_dummy() { return nullptr; }
Dummy* _dummy;
};
RCPP_MODULE(AF)
{
class_<Dummy>("Dummy")
.constructor();
class_<Wrap>("Wrap")
.constructor()
.method("get_dummy", &Wrap::dummy);
}
when Wrap$get_dummy is called in R. is.null() returns false. did some check, it seems that R_NilValue should be used. but to use R_NilValue, return type of get_dummy() needs to be SEXP.
is it a must to change get_dummy() as below
SEXP get_dummy() { return R_NilValue; // or return Rcpp::Module_wrap<Dummy *>(_dummy) if a valid pointer is intended.

Is there a C++ new declaration like in C#

I wondered if there was a new declaration like in C# for C++
C# allows you to do this and it just neatens up the code a bit:
FuncCall( new Foo() {
Bar = "sausage",
Boo = 4
} );
It's just I thought this was a bit sloppy in C++:
unique_ptr<Foo> foo( new Foo() );
foo.Bar = "sausage";
foo.Boo = 4;
FuncCall( move( foo ) );
Foo might look like this:
class Foo
{
public:
Foo();
string Bar;
int Boo;
}
Why am i not just placing all into construct paramters?
Because it's stupid when you have to initalize so much:
Foo( int width, int height, string title, string className, string thjis, stihjrjoifger gfirejgoirejgioerjgoire ) It goes on forever... Whereas i already have the properties inside my class... So was just wondering if it could be done..
You might use a lambda:
FuncCall( []{ Foo f; f.Bar = "sausage"; f.Boo = 4; return f; }() );
Live example
Foo has to have a constructor or be an aggregate type:
class Foo {
std::string bar;
int boo;
public:
Foo(std::string s, int i) : bar(std::move(s)), boo(i) {}
};
void FuncCall(std::unique_ptr<Foo> ptr) {}
int main() {
FuncCall(make_unique<Foo>("sausage", 4));
}
struct Foo {
std::string bar;
int boo;
};
void FuncCall(std::unique_ptr<Foo> ptr) {}
int main() {
std::unique_ptr<Foo> foo(new Foo{"sausage", 4});
FuncCall(foo);
}
Or you can avoid pointers:
void FuncCall(Foo foo) {}
int main() {
FuncCall({sausage", 4});
}
Be aware that the following:
class Foo {
std::string m_bar = "Bar";
int m_baz = 3;
float m_boo = 4.2;
/* ... */
public:
Foo() {} // or Foo() = default or elision
};
int main() {
Foo f;
f.m_bar = "wunderBar";
}
Expands out to be along the lines of the following:
Foo* fptr = stack_allocate<Foo*>(sizeof(Foo));
// from ctor
fptr->m_bar.string("Bar"); // construct m_bar
fptr->m_baz.int(3);
fptr->m_boo.float(4.2);
// your code:
fptr->m_bar.operator=("wunderBar");
For similar reasons, you might want to look at the IL instructions for your C# construct - you'll find it's performing equally redundant operations (and in more complex situations, possibly boxing/unboxing).
Your C++ approach will also fail you when you incorporate non-copyable or non-movable types which will force you to pass pointers and/or bend your design.
What it /seems/ you are trying to do is recreate Python's optional parameters:
# C++-alike
class Foo(object):
def __init__(self, Bar, Baz, Boo):
...
# C#-alike:
class Foo(object):
def __init__(self, Bar="Bar", Baz=13, Boo=4.2):
...
C++ doesn't provide a direct way of doing this, the closest mechanisms are default parameters and operator overloading:
class Foo {
std::string m_bar = "Bar";
int m_baz = 3;
float m_boo = 4.2;
public:
Foo(std::string bar="Bar", int baz=3, int boo=6.1)
: m_bar(bar), m_baz(baz), m_boo(boo)
{}
/* Foo* f = new Foo(); => new Foo(bar="Bar", baz=13, boo=6.1);
* Foo* f = new Foo("hello"); => new Foo(bar="hello", baz=3, boo=4.2);
* Foo* f = new Foo("hello", 1, 1.); => new Foo(bar="hello", baz=1, boo=1.);
* Foo* f = new Foo(42.); => invalid, arguments must be in order.
*/
};
or
class Foo {
std::string m_bar = "Bar";
int m_baz = 3;
float m_boo = 4.2;
public:
Foo() = default;
// allow Foo("hello")
Foo(const char* bar) : m_bar(bar) {}
Foo(const std::string& bar) : m_bar(bar) {}
Foo(std::string&& bar) : m_bar(std::forward(bar)) {}
// allow Foo(10, 12.)
explicit Foo(int baz, float boo) : m_baz(baz), m_boo(boo) {}
/* Foo* f = new Foo(); => new Foo(bar="Bar", baz=3, boo=4.2);
* Foo* f = new Foo("hello"); => new Foo(bar="hello", baz=3, boo=4.2);
* Foo* f = new Foo(1, 1.); => new Foo(bar="Bar", baz=1, boo=1.);
* Foo* f = new Foo(42.); => invalid, no match
*/
};
See http://ideone.com/yFIqlA for SSCE.
If you genuinely have a dozen different constructor configurations, you should probably rethink your design.
--- Edit ---
Note: It's not compulsory that you expose all parameters in the constructor:
class Foo {
std::string m_user_supplied;
std::time_t m_time;
public:
Foo() : m_user_supplied(), m_time(0) {}
Foo(std::string src) : m_user_supplied(src), m_time(0) {}
void addTime(time_t inc) { m_time += inc; }
};
--- Edit 2 ---
"should maybe rethink your design" ... One problem with large, optional lists of parameters is growth. You are likely to wind up with parameters that depend on each other, contradict each other or interact with each other. You can either choose not to validate these or you can end up with complicated constructors.
struct Foo {
...
FILE* m_output;
const char* m_mode;
...
Foo(..., FILE* output, const char* mode, ...)
{
...
if (output != nullptr) {
ASSERT( output == nullptr || mode != nullptr );
... other requirements
} else {
if (mode != nullptr)
... might not be an error but it might be a bug ...
}
...
}
};
One approach to avoiding this is to use encapsulation/aggregation of related members.
class Foo {
...
struct FileAccess {
FILE* m_file;
const char* m_mode;
constexpr FileAccess() : m_file(nullptr), m_mode(nullptr) noexcept {}
FileAccess(FILE* file, const char* mode) : m_file(file), m_mode(mode) {
if (file == nullptr || mode == nullptr)
throw invalid_argument("file/mode cannot be null");
}
};
...
FileAccess m_access;
Foo(..., FileAccess access, ...);
};
This can go a fair way to reducing the bloat. If your API is stable, you can use it with initializer lists (if your API is not stable and you do change will bite you in the ass)
auto fooWithFile = make_unique<Foo>{..., /*access=*/{stdout, "w"}, ...};
auto fooWithout = make_unique<Foo>{..., /*access=*/{}, ...};
If you subsequently decide to stop using ctors and switch to using setters, this will translate reasonably well, since you can have overloaded "set" which takes one of the various configuration structs:
auto foo = make_unique<Foo>();
foo->set(FileAccess(stdout, "w"))
->set(Position(Right, -100, Top, 180))
->set(DimensionPercentage(80, 75));
vs
auto foo = make_unique<Foo>() { # pseudo based on if C++ had the C# syntax
m_file = stdout;
m_mode = "w";
m_xPosition = -100;
m_xPositionRel = Right;
m_yPosition = -180;
m_yPositionRel = Top;
m_dimensionType = Percentage;
m_xDimension = 80;
m_yDimension = 75;
};
You can use uniform initialization to initialize it.