AnyCore PlatformBase

Files CCore/inc/base/PlatformBase.h CCore/src/base/PlatformBase.cpp CCore/src/base/PlatformBase.s

This part defines some basic types, constants and other entities, related with the target hardware and software platform.


#ifndef CCore_inc_base_PlatformBase_h
#define CCore_inc_base_PlatformBase_h

/* target label */

#define CCORE_TARGET WIN32

/* init priority */ 

#define CCORE_INITPRI_0 __attribute__((init_priority(101)))
#define CCORE_INITPRI_1 __attribute__((init_priority(102)))
#define CCORE_INITPRI_2 __attribute__((init_priority(103)))
#define CCORE_INITPRI_3 __attribute__((init_priority(104)))

/* inlining disabler */ 

#define CCORE_NOINLINE __attribute__((noinline))

/* includes */ 

#include <cstddef>
#include <type_traits>
#include <initializer_list>
#include <utility>

/* restrict */ 

#define restrict __restrict

/* namespace CCore */ 

namespace CCore {

/* consts */ 

const bool IsLEPlatform  = true ;

const bool Is2sComplementArithmetic = true ;

const unsigned MaxBitLen = 64   ;

const unsigned MaxAlign  = 16   ;

/* types */ 

using ulen = unsigned int ;
using uptr = unsigned int ;
 
using uint8  =      unsigned char ;
using uint16 =     unsigned short ;
using uint32 =       unsigned int ;
using uint64 = unsigned long long ; 

using sint8  =        signed char ;
using sint16 =       signed short ; 
using sint32 =         signed int ; 
using sint64 =   signed long long ; 

/* consts */ 

const ulen DefaultPacketCount = 50'000 ;

const unsigned DefaultEventElementCount = 10'000 ;

/* namespace Bits */ 

namespace Bits {

const unsigned unsigned_char      =  8 ;
const unsigned unsigned_short     = 16 ;
const unsigned unsigned_int       = 32 ;
const unsigned unsigned_long      = 32 ;
const unsigned unsigned_long_long = 64 ;

} // namespace Bits

/* namespace ExtraInt */

namespace ExtraInt {

/* classes */

template <class T> struct Prop;

/* struct Prop<T> */

template <class T> 
struct Prop 
 {
  enum 
   {
    IsSigned   = false,
    IsUnsigned = false
   };
 };

// 
// template <> 
// struct Prop<???> 
//  {
//   enum 
//    {
//     IsSigned   = true,
//     IsUnsigned = false,
//    };
//   
//   using SType = ??? ;
//   using UType = ??? ;
//   
//   using PromoteSType = ??? ;
//   using PromoteUType = ??? ;
//  };
// 
// template <> 
// struct Prop<???> 
//  {
//   enum 
//    {
//     IsSigned   = false,
//     IsUnsigned = true,
//       
//     Bits = ???  
//    };
//   
//   using PromoteUType = ??? ;
//  };
// 

} // namespace ExtraInt

/* namespace Meta */

namespace Meta {

/* classes */

template <class UInt> struct DoubleUIntCtor;

/* struct DoubleUIntCtor<UInt> */

template <class UInt> 
struct DoubleUIntCtor
 {
  using Ret = void ;
 };
 
template <> 
struct DoubleUIntCtor<uint8>
 {
  using Ret = uint16 ;
 };
 
template <> 
struct DoubleUIntCtor<uint16>
 {
  using Ret = uint32 ;
 };
 
template <> 
struct DoubleUIntCtor<uint32>
 {
  using Ret = uint64 ;
 };

/* type DoubleUInt<UInt> */

template <class UInt>
using DoubleUInt = typename DoubleUIntCtor<UInt>::Ret ;

} // namespace Meta

/* Used() */ 

template <class T> void Used(T &) {}
 
/* OptimizeBarrier() */
 
void OptimizeBarrier(void *ptr,ulen len);

} // namespace CCore
 
#endif

Defines and includes


/* target label */

#define CCORE_TARGET WIN32

/* init priority */ 

#define CCORE_INITPRI_0 __attribute__((init_priority(101)))
#define CCORE_INITPRI_1 __attribute__((init_priority(102)))
#define CCORE_INITPRI_2 __attribute__((init_priority(103)))
#define CCORE_INITPRI_3 __attribute__((init_priority(104)))

/* inlining disabler */ 

#define CCORE_NOINLINE __attribute__((noinline))

/* includes */ 

#include <cstddef>
#include <type_traits>
#include <initializer_list>
#include <utility>

/* restrict */ 

#define restrict __restrict

Macro CCORE_TARGET defines the target label, like WIN32, WIN64 etc...

Macros CCORE_INITPRI_0, CCORE_INITPRI_1, CCORE_INITPRI_2 and CCORE_INITPRI_3 are used to specify initialization priorities of global objects. For the gcc family of compilers they have values shown above. If the target use another compiler you must provide a proper substitution. This feature is not standard. Priority 0 is highest.

CCORE_NOINLINE is used to disable function inlining. This macro may be leave empty.

The set of standard include files, shown above, must be included, you may add any other desirable includes here.

restrict is a restrict keyword. This feature is still missing in the C++ standard, but major compilers support it. You must provide a proper definition of this macro.

Basic types


using ulen = unsigned int ;
using uptr = unsigned int ;
 
using uint8  =      unsigned char ;
using uint16 =     unsigned short ;
using uint32 =       unsigned int ;
using uint64 = unsigned long long ; 

using sint8  =        signed char ;
using sint16 =       signed short ; 
using sint32 =         signed int ; 
using sint64 =   signed long long ; 

This set of type definitions must be provided.

uintXXX is an unsigned integral type with the XXX bit length.

sintXXX is a 2'c signed integral types with the XXX bit length. Such types must be available on the target platform. For the latest gcc family of compilers you should turn on the option -fwrapv to ensure the proper type behavior.

ulen is the unsigned integral type with the "address length" bit length. You can use the standard type size_t for it. This type must have the sufficient value range to represent any object range length.

uptr is the unsigned integral type. It must be large enough to represent any pointer value. I.e. two-cast (T *)(uptr)ptr must restore the original value of any pointer.

Basic constants


/* consts */ 

const bool IsLEPlatform  = true ;

const bool Is2sComplementArithmetic = true ;

const unsigned MaxBitLen = 64   ;

const unsigned MaxAlign  = 16   ;

/* consts */ 

const ulen DefaultPacketCount = 50'000 ;

const unsigned DefaultEventElementCount = 10'000 ;

/* namespace Bits */ 

namespace Bits {

const unsigned unsigned_char      =  8 ;
const unsigned unsigned_short     = 16 ;
const unsigned unsigned_int       = 32 ;
const unsigned unsigned_long      = 32 ;
const unsigned unsigned_long_long = 64 ;

} // namespace Bits

IsLEPlatform is true, iff the target is little-endian.

Is2sComplementArithmetic is true, iff the target integral arithmetic is 2's complement. Currently it's the only option!

MaxBitLen is the maximum bit length of the unsigned integral types.

MaxAlign is the maximum of alignment of the target types.

DefaultPacketCount is the number of packets in the default packet pool by default.

DefaultEventElementCount this constant is used in the numbering of the event-generating objects. It should have the value like 5000-10000.

Bits::unsigned_ttt is the bit length of the correspondent unsigned integral type.

Extra integral types


/* namespace ExtraInt */

namespace ExtraInt {

/* classes */

template <class T> struct Prop;

/* struct Prop<T> */

template <class T> 
struct Prop 
 {
  enum 
   {
    IsSigned   = false,
    IsUnsigned = false
   };
 };

// 
// template <> 
// struct Prop<???> 
//  {
//   enum 
//    {
//     IsSigned   = true,
//     IsUnsigned = false,
//    };
//   
//   using SType = ??? ;
//   using UType = ??? ;
//   
//   using PromoteSType = ??? ;
//   using PromoteUType = ??? ;
//  };
// 
// template <> 
// struct Prop<???> 
//  {
//   enum 
//    {
//     IsSigned   = false,
//     IsUnsigned = true,
//       
//     Bits = ???  
//    };
//   
//   using PromoteUType = ??? ;
//  };
// 

} // namespace ExtraInt

The structure ExtraInt::Prop can be used to support extra integral types, i.e. types not from the standard list of the integral types, if such types are supported by the compiler. If you want to use any of such type with the CCore, you should provide its properties, using a specialization of the structure ExtraInt::Prop as shown above. For a signed integral type the specialized structure defines both signed and unsigned types and desirable promote types. For an unsigned integral type the specialized structure defines bit length and desirable promote type.

Meta tools


/* namespace Meta */

namespace Meta {

/* classes */

template <class UInt> struct DoubleUIntCtor;

/* struct DoubleUIntCtor<UInt> */

template <class UInt> 
struct DoubleUIntCtor
 {
  using Ret = void ;
 };
 
template <> 
struct DoubleUIntCtor<uint8>
 {
  using Ret = uint16 ;
 };
 
template <> 
struct DoubleUIntCtor<uint16>
 {
  using Ret = uint32 ;
 };
 
template <> 
struct DoubleUIntCtor<uint32>
 {
  using Ret = uint64 ;
 };

/* type DoubleUInt<UInt> */

template <class UInt>
using DoubleUInt = typename DoubleUIntCtor<UInt>::Ret ;

} // namespace Meta

This is a small collection of meta-tools.

DoubleUInt is a Meta-type. It yields the double bit length type of the given unsigned integral type or the void, if such type does not exist.

Special functions


/* Used() */ 

template <class T> void Used(T &) {}
 
/* OptimizeBarrier() */
 
void OptimizeBarrier(void *ptr,ulen len);

Used() this function is used to disable the "unused argument" (or local variable) warning.

OptimizeBarrier() is used to suppress the compiler optimization. It should be implemented in such a way, that compiler could not be able to learn its semantic. For example, using assembler. This function does nothing. From the compiler perspective, however, this function does something unknown with the given memory range.