Let's say I have 3 classes. I expect sizeof() each class to be exactly the same--say 512 bytes.
How can I use something like BOOST_STATIC_ASSERT to apply to all of them such that
I only need to use BOOST_STATIC_ASSERT in a single place (DRY principle)
Evaluated once at compile-time and not run-time
Note: we can use whatever C++ techniques we want (create more class , use inheritance, etc)
My naive solution is presented below:
class A { ...stuff }; BOOST_STATIC_ASSERT( sizeof(A) == 512 );
class B { ...stuff }; BOOST_STATIC_ASSERT( sizeof(B) == 512 );
class C { ...stuff }; BOOST_STATIC_ASSERT( sizeof(C) == 512 );
This seems to work with gcc 4.0.1 and boost 1.39:
template <typename T, size_t S>
struct enforce_size
{
enforce_size()
{
BOOST_STATIC_ASSERT( sizeof( T ) == S );
}
};
class A: enforce_size<A,512> { /* stuff */ };
As those classes have no relationship, I see now way to do this because you have to be explicit about witch types you want to be checked.
The only DRY way to enforce this is what Nikolai N Festissov proposed. I was writting a similar example with some minor modifications, but the global idea is to make a boost::nocopy - like class that will force the child class to be of a given size.
template< typename CheckedType, size_t FixedSize >
class SizeChecked // simple, no inheritance overload
{
public:
SizeChecked()
{
// c++0x or compilers with static_assert() available
//static_assert( sizeof( CheckedType ) == FixedSize, "Type size check failed!" );
BOOST_STATIC_ASSERT( sizeof( CheckedType ) == FixedSize );
}
};
template< typename CheckedType >
class Size512 : public SizeChecked< CheckedType, 512 > // simple, no inheritance overload
{};
////////////////////////////////////////////////////////////////////
class A : Size512< A > // automatically check
{
};
class B : Size512< B > // automatically check
{
std::array< char, 512 > m_array;
};
class C : SizeChecked< C, 1 >
{
char m_char;
};
class D : SizeChecked< D, 4 >
{
short m_k;
char m_u;
};
int wmain()
{
// need instantiation to be checked !
//A a; // will trigger the assertion at compile time
B b; // sizeof(B) == 512 : will be fine
C c; // sizeof(C) == 1 : will be fine
//D d; // will fail because sizeof( short ) + sizeof( char ) != 4 !
}
Beware : if you loose inheritance you still have to provide an explicit check on the child classes, the check is not inherited!
By the way, a possible way to be more DRY would be to put all your static assertion in only one place.
Related
I want to determine which object 'owns' some other object.
I have a situation similar to the code below. Filling in the blanks, it compiles and seems to do what I expect - but will this work in general? Is there some idiomatic way to do this? Or is ill-advised altogether?
#include <functional>
#include <vector>
#include <iostream>
using namespace std;
struct A { int blah; /* ... */ };
struct B : A { /* ... */ };
struct C { vector<A> as{{}}; /*.. */ };
struct D { vector<C> cs{{}}; /*.. */ };
const A& superFoo(vector<reference_wrapper<const A>> alsoa) { alsoa.back();}
int main() {
B b{};
D d{};
const A& ds_a = /* Some selected 'a' from 'd' */;
vector<reference_wrapper<const A>> sfIn = {ref(b), ref(dads)};
auto out = superFoo(sfIn){ /* Some special selection process, based on A's attributes. */};
void* address = reinterpret_cast<void*>(&out);
/* Here I want to attribute which object, b or d, 'owns' the returned 'a' - 'out' */
if (address < reinterpret_cast<void*>(&b) + sizeof(b) &&
address >= reinterpret_cast<void*>(&b))
{ cout<< "b";
if (address < reinterpret_cast<void*>(&d) + sizeof(D) &&
address >= reinterpret_cast<void*>(&b))
{ cout<< "d"; }
}
The problem that you have is that each of the struct A through D all are composited in memory. Honestly, the real problem here is, how on earth do you come up with that pointer you are feeding to superfoo to begin with? If it came from one of your objects, then can you not tag it as such.
That's really a design problem. In general, C++ simply isn't designed to determine if an object is in a particular graph, but if you must, then:
To do this correctly, you would need to define something like so:
(Warning, this is off the top of my head)
struct PlainOldDataOnly
{
bool isMe(char *x) { return x >= (char *)this && x < (char *)this + sizeof(PlainOldDataOnly); }
}
struct HasVectors : PlainOldDataOnly
{
vector<myPlainOldData> stuff;
bool isMe(char *x) { return PlainOldDataOnly::isMe(x) || (x >= (char *)stuff.data() && x < (char *)(stuff.data() + stuff.size()); }
}
Note that in HasVectors, you would have to have that construct of stuff for every vector, and then, it could only work if and only if:
a) The vector(s) consists of only plain old data.
b) The vector(s) are not resized.
As others have said, this is very brittle code. The moment you put a map, a string, or something else into the objects in the vector, then you will run into problems. This would be a real pain to maintain.
To start with, I'm using VC++ 2015 U3 and I am looking for an answer that is specific to that compiler.
I have a struct that has a char data[1] as its last member, which is a placeholder for embedded data. I'd like to make it cleaner to just derive a template struct from that which takes a size_t indicating how much data is after it. Like so:
// This is a placeholder for any WINAPI structs that has this form
struct base_struct
{
DWORD stuff;
char data[1];
};
template <size_t DATA_SIZE>
struct my_struct : base_struct
{
char rest_of_data[DATA_SIZE - 1];
};
However, there is an alignment issue. The rest_of_data is located 4 bytes away from data of the base class. This is annoying. I've tried to use #pragma pack(push,1)/#pragma pack(pop), __declspec(align(1)), but I can't seem to get the derived data to immediately follow the base data.
Perhaps I'm not using them correctly? Is there a way of doing this?
P.S., I already know I can do a lot of tricks to manage the memory and use reinterpret_cast, but I would like to see if this is a viable option first.
P.P.S. base_struct is not my struct. It is any number of struct that are part of the WINAPI. It is not up to me to update or modify it, that is why I am attempting to make something that I can build on top of the already defined structs for.
EDIT
I've attempted using the has-a rather than the is-a relationship, and I got something odd happening. offsetof() is saying that the position is correct, but when I get the actual address position, it is aligned. sigh
#include <iostream>
#include <windows.h>
#define report_success(x) (!(x) ? (void)0 : (void)(std::cout << #x << std::endl))
int main()
{
struct old_t
{
DWORD stuff;
CHAR data[1];
};
struct new_t
{
old_t __declspec(align(1)) internal;
char __declspec(align(1)) extended_data[1];
};
new_t x;
///////////////////////////////////////////////////////////////////////////// padded //////////// not padded /////
//////////////////////////////////////////////////////////////////////// should | actually || should | actually //
report_success(offsetof(new_t, extended_data) == sizeof(old_t) + 0); // T | T || T | T //
report_success(offsetof(new_t, extended_data) == sizeof(old_t) + 1); // F | F || F | F //
report_success(offsetof(new_t, extended_data) == sizeof(old_t) + 2); // F | F || F | F //
report_success(offsetof(new_t, extended_data) == sizeof(old_t) + 3); // F | F || F | F //
report_success(&x.extended_data[0] == &x.internal.data[1]); // T | F || T | F //
report_success(&x.extended_data[0] == &x.internal.data[2]); // F | F || F | F //
report_success(&x.extended_data[0] == &x.internal.data[3]); // F | F || F | F //
report_success(&x.extended_data[0] == &x.internal.data[4]); // F | T || F | T //
return 0;
}
Expected output:
offsetof(new_t, extended_data) == sizeof(old_t) + 0
&x.extended_data[0] == &x.internal.data[1]
Actual output:
offsetof(new_t, extended_data) == sizeof(old_t) + 0
&x.extended_data[0] == &x.internal.data[4]
Demo
Looks like the best I can do is to use a template struct with an anonymous union containing the old type and an anonymous struct with padding and the actual data.
template <typename OLD_T, size_t DATA_START, size_t SIZE>
struct new_t
{
union
{
OLD_T internal;
struct
{
char __declspec(align(1)) padding[DATA_START];
char __declspec(align(1)) extended_data[SIZE];
};
};
operator OLD_T&() { return internal; }
OLD_T* operator&() { return &internal; }
};
new_t<old_t, offsetof(old_t, data), 5> object_with_5_char_array_at_end;
Here, extended_data is actually placed at the same location as data. I could have placed it after it to answer this question as asked, but the anonymous struct really isn't used anyway, so I went with cleaner calculations.
This doesn't use the #pragma pack so that the entire struct can be properly aligned for speed. It's unfortunate that I have to have a level of indirection to access the original object, but at least I can define the conversion operator so I can at least pass this as if it was the original object type and addressof operator so I can get the address of the original type as the original type pointer.
Too bad a union couldn't inherit from a struct to remove the extra layer of indirection. Of course that could open up a whole other can of worms. :)
The short answer is, you can't do what you are asking for. The compiler is free to insert padding between base_struct and my_struct as it sees fit, and you can't tell it not to do so.
If you are going to use templates anyway, consider passing a template parameter to specify the desired type of data, instead of using char[1], eg:
template <typename T>
struct base_struct
{
...
T data;
};
And then define types for data to use, eg:
template <size_t DATA_SIZE>
struct data_buffer
{
char buffer[DATA_SIZE];
};
Or, in C++11 and later:
template <size_t DATA_SIZE>
using data_buffer = char[DATA_SIZE];
Then you can use base_struct<data_buffer<...> >, eg:
template <size_t DATA_SIZE>
struct my_struct : base_struct<data_buffer<DATA_SIZE> >
{
};
Or, at the very least, specify the full size of base_struct::data[] as a template parameter:
template <size_t DATA_SIZE>
struct base_struct
{
...
char data[DATA_SIZE];
};
template <size_t DATA_SIZE>
struct my_struct : base_struct<DATA_SIZE>
{
};
UPDATE:
base_struct is not my struct. It is any number of struct that are part of the WINAPI
In that case, consider using a approach similar to NMHDR and its descendants (NMLISTVIEW, NMTREEVIEW, etc). Instead of deriving my_struct from base_struct, have my_struct contain a base_struct member. Then you can byte-align an additional data member up against the end of the base_struct member:
struct win32_struct
{
DWORD stuff;
char data[1];
};
#pragma pack(push, 1)
template <size_t DATA_SIZE>
struct my_struct
{
win32_struct base;
char rest_of_data[DATA_SIZE - (sizeof(win32_struct) - offsetof(win32_struct, data))];
};
#pragma pack(pop)
I came across these lines of code:
template< int I > struct arg
{
arg()
{
}
template< class T > arg( T const & /* t */ )
{
// static assert I == is_placeholder<T>::value
typedef char T_must_be_placeholder[ I == is_placeholder<T>::value? 1: -1 ];
}
};
template< class T > struct is_placeholder
{
enum _vt { value = 0 };
};
What could be the reason the struct is_placeholder is templated while typename T is not used anywhere inside?
Why T_must_be_placeholder is defined in such a way so that it can have invalid size -1. To realise this, I called arg<1>(1) and it gave error: size of array is negative as expected. Is it some sort of sanity-check technique? Why doesn't the compiler report this issue if the arg<1>(1) call is not made?
While
int i = 0;
char a[i == 1 ? 1 : -1]; //No error
If sanity check works for 1st example, then how does it fail for second one?
is_placeholder is a template so that it can be specialized for different T. Say I create a struct example and want is_placeholder<example>::value to be 42. I would do this:
struct example {};
template< class T > struct is_placeholder
{
enum _vt { value = 0 };
};
template<>
struct is_placeholder<example>
{
enum _vt { value = 42 };
};
template< int I > struct arg
{
arg()
{
}
template< class T > arg( T const & /* t */ )
{
// static assert I == is_placeholder<T>::value
typedef char T_must_be_placeholder[ I == is_placeholder<T>::value ? 1: -1 ];
}
};
void test()
{
auto x = arg<42>(example()); // compiles
auto y = arg<43>(example()); // assertion
return 0;
}
In this case T_must_be_placeholder checks if is_placeholder<example>::value (which we just specialized to be 42) is the same as I. So if I is 42 it compiles, but if I is anything else, it won't.
Attempting to create an array with negative size is a way of deliberately preventing the code from compiling, so yes, this is probably a sanity check (static assertion, as it says in the comment).
I have two big C structures used in a C legacy code, and I need to convert from one to another, and the other way around. Something like this :
#include <iostream>
struct A {
int a;
float b;
};
struct B {
char a;
int b;
};
struct C {
A a;
B b;
};
struct D {
int a;
char b;
float c;
};
void CtoD( const C& c, D &d ) {
d.a = c.a.a;
d.b = c.b.a;
d.c = c.a.b;
}
void DtoC( const D &d, C& c ) {
c.a.a = d.a;
c.b.a = d.b;
c.a.b = d.c;
}
int main()
{
C c = { { 1, 3.3f }, { 'a', 4 } };
D d = { 1, 'b', 5.5f };
#if 0
CtoD( c, d );
#else
DtoC( d, c );
#endif
std::cout<<"C="<<c.a.a<<" "<<c.a.b<<" "<<c.b.a<<" "<<c.b.b<<std::endl;
std::cout<<"D="<<d.a<<" "<<d.b<<" "<<d.c<<std::endl;
}
Functions CtoD and DtoC are doing the same thing, but in opposite direction. Changing one structure requires changing both of them.
To minimize possibility of an error, and to avoid repetition, I would like to implement some kind of mapping, where I define the connections only once, and then I copy one value to another. This way, only one change is needed if a structure changes.
So, the question is : how to do it? Is there perhaps a design pattern I could use?
My real structures have hundreds of fields. The above is just simplified example.
In your literal example, I don't think it's worth the hassle. Just write tests so that you ensure your conversions work well.
In your real code, if your structs have "hundreds of fields", your structs may be badly designed. Maybe they should be composed of smaller objects. I've never designed anything which required hunderds of fields in exactly the same struct object - instead, these fields allowed some kind of classification so that they could be treated in smaller bunches.
Since your code is legacy and you don't want to rewrite it, just write tests for your conversions functions, as I said above for the example.
Well tested code is no longer legacy code. Legacy code is basically code for which you don't have automated tests.
If rewriting it is not an option, testing it is a must.
About the cost of testing it "both ways", Idan Arye's comment below says everything:
Since the conversion is symmetric, testing it both ways is not that
much more work than testing it one way. All you need to do is init two
structs - C c and D d - and set them to be the converted versions of
each other. Then you just have to check that CtoD(c)==d and
DtoC(d)==c (or use comparison functions if you happen to have them
defined). The big work here is initializing c and d - but you would
have to do that anyways if you wanted to test one way conversion, so
adding the test for the other way is very cheap.
Let's get naughty...
struct rightwards_t {} rightwards;
struct leftwards_t {} leftwards;
template<typename Left, typename Right>
inline void map_field(Left& left, const Right& right, leftwards_t) {
left = right;
}
template<typename Left, typename Right>
inline void map_field(const Left& left, Right& right, rightwards_t) {
right = left;
}
template<typename Direction>
void convert(C& c, D& d, Direction direction) {
map_field(c.a.a, d.a, direction);
map_field(c.b.a, d.b, direction);
map_field(c.a.b, d.c, direction);
}
// Usage
C c;
D d;
convert(c, d, leftwards); // Converts d into c
convert(c, d, rightwards); // Converts c into d
Really don't know if it works (no compiler at hand), but I wanted to write it. If anyone can help me make it correct, please do.
You could do it with a container of hundreds of std::pairs of references to the sub-objects involved. With a references, you can both read and write, so reading from the left-object and writing to the right-object converts one-way. The opposite convert the other way.
Pick your favorite scripting language(if you don't have one yet I recommend Ruby) and write a small script that generate the conversion functions for you(both source and header files).
Unless you pick a lame scripting language, you can even represent the connections directly in the language, when calling the functions that generate the converters. For example, in Ruby after defining generate_converters you could write:
generate_converters :C,:D do
convert 'a.a','a'
convert 'b.a','b'
convert 'a.b','c'
end
I agree with Daniel, not worth the hassle, but you could write a little app that generates the code for you. You feed the app with description of two structs, and bindings between struct members, and the app generates the C code that is then compiled as usual.
Another alternative is to fiddle with pointers to members, but that could consume even more developer's time, so is even less worth the hassle than the first option.
It took me a while to figure out how to do this. And I came out with next solution :
#include <iostream>
#include <algorithm>
#include <cstring>
struct A {
int a;
float b;
};
struct B {
char a;
int b;
};
struct C {
A a;
B b;
};
struct D {
int a;
char b;
float c;
};
template< typename T1, typename T2 >
struct DataField
{
static inline void Update( const T1 & src, T2 & dst ) { dst = src; }
static inline void Update( T1 & dst, const T2 & src ) { dst = src; }
};
template<>
struct DataField< const char*, char* >
{
static inline void Update( const char* src, char* dst ) { strcpy( dst, src ); }
};
template<>
struct DataField< char*, const char* >
{
static inline void Update( char* dst, const char* src ) { strcpy( dst, src ); }
};
template< typename T1, typename T2, int N >
struct DataField< T1[N], T2[N] >
{
static inline void Update( const T1 (&src)[N], T2 (&dst)[N] ) { std::copy_n( src, N, dst ); }
static inline void Update( T1 (&dst)[N], const T1 (&src)[N] ) { std::copy_n( src, N, dst ); }
};
template< typename T1, typename T2 >
void UpdateDataField( T1 & src, T2 & dst )
{
DataField< T1, T2 >::Update( src, dst );
}
template< typename T1, typename T2 >
void UpdateMappedDataFields( T1 & src, T2 & dst )
{
UpdateDataField( src.a.a, dst.a );
UpdateDataField( src.a.b, dst.c );
UpdateDataField( src.b.a, dst.b );
}
void CtoD( const C& c, D &d ) {
UpdateMappedDataFields( c, d );
}
void DtoC( const D &d, C& c ) {
UpdateMappedDataFields( c, d );
}
int main()
{
C c = { { 1, 3.3f }, { 'a', 4 } };
D d = { 1, 'b', 5.5f };
#if 0
CtoD( c, d );
#else
DtoC( d, c );
#endif
std::cout<<"C="<<c.a.a<<" "<<c.a.b<<" "<<c.b.a<<" "<<c.b.b<<std::endl;
std::cout<<"D="<<d.a<<" "<<d.b<<" "<<d.c<<std::endl;
}
All data fields mapping is done in the UpdateMappedDataFields function, and only there.
What I don't like is that the function UpdateMappedDataFields is a template, and the way it is implemented, it prevents autocomplete when using IDEs, since the types are not known.
However, I would still like to hear if there is a better way.
Similar to what Idan and Dialecticus proposed, you can also just use your editor's search and replace function:
E.g. write CtoD manually, copy the body to DtoC and - in eclipse - use
Find: ^(.*)=(.*);
Replace: $2=$1;
in order to automatically swap the left and right side of each assignment in the body of DtoC.
Whether or not this is preferable to the usage of more or less complex c++ constructs depends on your specific code and requirements. In my opinion, the code is easier to read and maintain this way, but of course nothing enforces coherency between CtoD and DtoC after future changes (I'd mention the procedure in a code comment).
Let's say I have a set of flags and a class like this:
/// <summary>Options controlling a search for files.</summary>
enum class FindFilesOptions : unsigned char
{
LocalSearch = 0,
RecursiveSearch = 1,
IncludeDotDirectories = 2
};
class FindFiles : boost::noncopyable
{
/* omitted */
public:
FindFiles(std::wstring const& pattern, FindFilesOptions options);
/* omitted */
}
and I want a caller to be able to select more than one option:
FindFiles handle(Append(basicRootPath, L"*"),
FindFilesOptions::RecursiveSearch | FindFilesOptions::IncludeDotDirectories);
Is it possible to support this in a strongly-typed way with C++11 enum class, or do I have to revert to untyped enumerations?
(I know the caller could static_cast to the underlying type and static_cast back, but I don't want the caller to have to do that)
It is certainly possible to use enum classes for bitmaps. It is, unfortunately, a bit painful to do so: You need to define the necessary bit operations on your type. Below is an example how this could look like. It would be nice if the enum classes could derive from some other type which could live in a suitable namespace defining the necessary operator boilerplate code.
#include <iostream>
#include <type_traits>
enum class bitmap: unsigned char
{
a = 0x01,
b = 0x02,
c = 0x04
};
bitmap operator& (bitmap x, bitmap y)
{
typedef std::underlying_type<bitmap>::type uchar;
return bitmap(uchar(x) & uchar(y));
}
bitmap operator| (bitmap x, bitmap y)
{
typedef std::underlying_type<bitmap>::type uchar;
return bitmap(uchar(x) | uchar(y));
}
bitmap operator^ (bitmap x, bitmap y)
{
typedef std::underlying_type<bitmap>::type uchar;
return bitmap(uchar(x) ^ uchar(y));
}
bool test(bitmap x)
{
return std::underlying_type<bitmap>::type(x);
}
int main()
{
bitmap v = bitmap::a | bitmap::b;
if (test(v & bitmap::a)) {
std::cout << "a ";
}
if (test(v & bitmap::b)) {
std::cout << "b ";
}
if (test(v & bitmap::c)) {
std::cout << "c ";
}
std::cout << '\n';
}
Templates play well with enum class so you can define sets of operators that work on sets of similar enumeration types. The key is to use a traits template to specify what interface(s) each enumeration conforms/subscribes to.
As a start:
enum class mood_flag {
jumpy,
happy,
upset,
count // size of enumeration
};
template<>
struct enum_traits< mood_flag > {
static constexpr bool bit_index = true;
};
template< typename t >
struct flag_bits : std::bitset< static_cast< int >( t::count ) > {
flag_bits( t bit ) // implicit
{ this->set( static_cast< int >( bit ) ); }
// Should be explicit but I'm lazy to type:
flag_bits( typename flag_bits::bitset set )
: flag_bits::bitset( set ) {}
};
template< typename e >
typename std::enable_if< enum_traits< e >::bit_index,
flag_bits< e > >::type
operator | ( flag_bits< e > set, e next )
{ return set | flag_bits< e >( next ); }
template< typename e >
typename std::enable_if< enum_traits< e >::bit_index,
flag_bits< e > >::type
operator | ( e first, e next )
{ return flag_bits< e >( first ) | next; }
http://ideone.com/kJ271Z
GCC 4.9 reported that some implicit member functions were constexpr while I was getting this to compile, so the templates should probably be so as well.
This should probably also have a free function to_scalar or something which returns an unsigned integer type given either an individual flag or a flag_bits set.
How about defining FindFiles so that it takes std::initializer_list of FindFilesOptions.
void FindFiles(std::wstring const& pattern, std::initializer_list<FindFilesOptions> options)
{
auto has_option = [&](FindFilesOptions const option)
{
return std::find(std::begin(options), std::end(options), option) != std::end(options);
};
if (has_option(FindFilesOptions::LocalSearch))
{
// ...
}
if (has_option(FindFilesOptions::RecursiveSearch))
{
// ...
}
if (has_option(FindFilesOptions::IncludeDotDirectories))
{
// ...
}
}
Then you could call it like so:
FindFiles({}, {FindFilesOptions::RecursiveSearch, FindFilesOptions::IncludeDotDirectories});
The problem is not the explicit enum type but the class scope.
With C++11, enum as compile time constant loose a lot of interest compared to a bunch of constexpr when you need operate on the value ( bitwise operation, incrementation, etc)
If you don't care about performance, change your options to set<FindFilesOptions>!