Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define STRUCTSIZE(s) (sizeof(s) / sizeof(*s))
- template<typename T,int SIZE>
- inline size_t array_size(const T (&array)[SIZE])
- {
- return SIZE;
- }
- constexpr size_t array_size(const T (&array)[SIZE])
- #include <boost/typeof/typeof.hpp>
- template<typename T>
- struct ArraySize
- {
- private: static T x;
- public: enum { size = sizeof(T)/sizeof(*x)};
- };
- template<typename T>
- struct ArraySize<T*> {};
- ArraySize<BOOST_TYPEOF(foo)>::size
- // asize.hpp
- template < typename T >
- struct asize; // no implementation for all types...
- template < typename T, size_t N >
- struct asize< T[N] > { // ...except arrays
- static const size_t val = N;
- };
- template< size_t N >
- struct count_type { char val[N]; };
- template< typename T, size_t N >
- count_type< N > count( const T (&)[N] ) {}
- #define ASIZE( a ) ( sizeof( count( a ).val ) )
- #define ASIZET( A ) ( asize< A >::val )
- // asize_test.cpp
- #include <boost/static_assert.hpp>
- #include "asize.hpp"
- #define OLD_ASIZE( a ) ( sizeof( a ) / sizeof( *a ) )
- typedef char C;
- typedef struct { int i; double d; } S;
- typedef C A[42];
- typedef S B[42];
- typedef C * PA;
- typedef S * PB;
- int main() {
- A a; B b; PA pa; PB pb;
- BOOST_STATIC_ASSERT( ASIZET( A ) == 42 );
- BOOST_STATIC_ASSERT( ASIZET( B ) == 42 );
- BOOST_STATIC_ASSERT( ASIZET( A ) == OLD_ASIZE( a ) );
- BOOST_STATIC_ASSERT( ASIZET( B ) == OLD_ASIZE( b ) );
- BOOST_STATIC_ASSERT( ASIZE( a ) == OLD_ASIZE( a ) );
- BOOST_STATIC_ASSERT( ASIZE( b ) == OLD_ASIZE( b ) );
- BOOST_STATIC_ASSERT( OLD_ASIZE( pa ) != 42 ); // logic error: pointer accepted
- BOOST_STATIC_ASSERT( OLD_ASIZE( pb ) != 42 ); // logic error: pointer accepted
- // BOOST_STATIC_ASSERT( ASIZE( pa ) != 42 ); // compile error: pointer rejected
- // BOOST_STATIC_ASSERT( ASIZE( pb ) != 42 ); // compile error: pointer rejected
- return 0;
- }
- template<int n>
- struct char_array_wrapper{
- char result[n];
- };
- template<typename T, int s>
- char_array_wrapper<s> the_type_of_the_variable_is_not_an_array(const T (&array)[s]){
- }
- #define ARRAYSIZE_OF_VAR(v) sizeof(the_type_of_the_variable_is_not_an_array(v).result)
- #include <iostream>
- using namespace std;
- int main(){
- int foo[42];
- int*bar;
- cout<<ARRAYSIZE_OF_VAR(foo)<<endl;
- // cout<<ARRAYSIZE_OF_VAR(bar)<<endl; fails
- }
- template< typename T > size_t structsize( const T& t ) {
- return sizeof( t ) / sizeof( *t );
- }
- int ints[] = { 1,2,3 };
- assert( structsize( ints ) == 3 );
- //
- // Return the number of elements in a statically sized array.
- // DWORD Buffer[100];
- // RTL_NUMBER_OF(Buffer) == 100
- // This is also popularly known as: NUMBER_OF, ARRSIZE, _countof, NELEM, etc.
- //
- #define RTL_NUMBER_OF_V1(A) (sizeof(A)/sizeof((A)[0]))
- #if defined(__cplusplus) &&
- !defined(MIDL_PASS) &&
- !defined(RC_INVOKED) &&
- !defined(_PREFAST_) &&
- (_MSC_FULL_VER >= 13009466) &&
- !defined(SORTPP_PASS)
- //
- // RtlpNumberOf is a function that takes a reference to an array of N Ts.
- //
- // typedef T array_of_T[N];
- // typedef array_of_T &reference_to_array_of_T;
- //
- // RtlpNumberOf returns a pointer to an array of N chars.
- // We could return a reference instead of a pointer but older compilers do not accept that.
- //
- // typedef char array_of_char[N];
- // typedef array_of_char *pointer_to_array_of_char;
- //
- // sizeof(array_of_char) == N
- // sizeof(*pointer_to_array_of_char) == N
- //
- // pointer_to_array_of_char RtlpNumberOf(reference_to_array_of_T);
- //
- // We never even call RtlpNumberOf, we just take the size of dereferencing its return type.
- // We do not even implement RtlpNumberOf, we just decare it.
- //
- // Attempts to pass pointers instead of arrays to this macro result in compile time errors.
- // That is the point.
- //
- extern "C++" // templates cannot be declared to have 'C' linkage
- template <typename T, size_t N>
- char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N];
- #define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A)))
- //
- // This does not work with:
- //
- // void Foo()
- // {
- // struct { int x; } y[2];
- // RTL_NUMBER_OF_V2(y); // illegal use of anonymous local type in template instantiation
- // }
- //
- // You must instead do:
- //
- // struct Foo1 { int x; };
- //
- // void Foo()
- // {
- // Foo1 y[2];
- // RTL_NUMBER_OF_V2(y); // ok
- // }
- //
- // OR
- //
- // void Foo()
- // {
- // struct { int x; } y[2];
- // RTL_NUMBER_OF_V1(y); // ok
- // }
- //
- // OR
- //
- // void Foo()
- // {
- // struct { int x; } y[2];
- // _ARRAYSIZE(y); // ok
- // }
- //
- #else
- #define RTL_NUMBER_OF_V2(A) RTL_NUMBER_OF_V1(A)
- #endif
- #ifdef ENABLE_RTL_NUMBER_OF_V2
- #define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V2(A)
- #else
- #define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V1(A)
- #endif
- //
- // ARRAYSIZE is more readable version of RTL_NUMBER_OF_V2, and uses
- // it regardless of ENABLE_RTL_NUMBER_OF_V2
- //
- // _ARRAYSIZE is a version useful for anonymous types
- //
- #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)
- #define _ARRAYSIZE(A) RTL_NUMBER_OF_V1(A)
- template<typename T, int SIZE>
- int arraySize(const T(&arr)[SIZE])
- {
- return SIZE;
- }
- template <typename T>
- uint32_t StructSize() // This might get inlined to a constant at compile time
- {
- return sizeof(T)/sizeof(*T);
- }
- // or to get it at compile time for shure
- class StructSize<typename T>
- {
- enum { result = sizeof(T)/sizeof(*T) };
- }
- #include <iterator>
- #include <algorithm>
- #include <iostream>
- template<typename T>
- struct StructSize
- {
- private: static T x;
- public: enum { size = sizeof(T)/sizeof(*x)};
- };
- template<typename T>
- struct StructSize<T*>
- {
- /* Can only guarantee 1 item (maybe we should even disallow this situation) */
- //public: enum { size = 1};
- };
- struct X
- {
- int operator *();
- };
- int main(int argc,char* argv[])
- {
- int data[] = {1,2,3,4,5,6,7,8};
- int copy[ StructSize<typeof(data)>::size];
- std::copy(&data[0],&data[StructSize<typeof(data)>::size],©[0]);
- std::copy(©[0],©[StructSize<typeof(copy)>::size],std::ostream_iterator<int>(std::cout,","));
- /*
- * For extra points we should make the following cause the compiler to generate an error message */
- X bad1;
- X bad2[StructSize<typeof(bad1)>::size];
- }
- template <typename T>
- size_t getTypeSize()
- {
- return sizeof(T)/sizeof(*T);
- }
- struct JibbaJabba
- {
- int int1;
- float f;
- };
- int main()
- {
- cout << "sizeof JibbaJabba is " << getTypeSize<JibbaJabba>() << std::endl;
- return 0;
- }
Add Comment
Please, Sign In to add comment