/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see .
Description
Test the sizeof for basic types.
Also tests how the data mapping of OpenFOAM types to UPstream (MPI)
type ids are handled.
Can be compiled and run without any OpenFOAM libraries.
g++ -std=c++17 -oTest-machine-sizes Test-machine-sizes.cpp
\*---------------------------------------------------------------------------*/
#include
#include
#include
#include
#include
#include
#include
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Partial copy from UPstream.H
//- Some MPI data types
//
//- Mapping of some fundamental and aggregate types to MPI data types
enum class dataTypes : int
{
// Builtin Types [8]:
DataTypes_begin, //!< Begin builtin types (internal use)
type_byte = DataTypes_begin, // also for char, unsigned char
type_int32,
type_int64,
type_uint32,
type_uint64,
type_float,
type_double,
type_long_double,
invalid
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Partial copy from UPstreamTraits.H
//- A supported UPstream data type (intrinsic or user-defined)
template
struct UPstream_base_dataType : std::false_type
{
static constexpr auto datatype_id = dataTypes::invalid;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Specializations of the above,
// each to match the elements of UPstream::dataTypes
#undef defineUPstreamDataTraits
#define defineUPstreamDataTraits(TypeId, Type) \
template<> struct UPstream_base_dataType : std::true_type \
{ \
static constexpr auto datatype_id = dataTypes::TypeId; \
};
defineUPstreamDataTraits(type_byte, char);
defineUPstreamDataTraits(type_byte, unsigned char);
defineUPstreamDataTraits(type_int32, int32_t);
defineUPstreamDataTraits(type_int64, int64_t);
defineUPstreamDataTraits(type_uint32, uint32_t);
defineUPstreamDataTraits(type_uint64, uint64_t);
defineUPstreamDataTraits(type_float, float);
defineUPstreamDataTraits(type_double, double);
defineUPstreamDataTraits(type_long_double, long double);
#undef defineUPstreamDataTraits
//- Explicit handling of data type aliases. This is necessary since
//- different systems map things like 'unsigned long' differently but we
//- restrict ourselves to int32/int64 types
template
struct UPstream_alias_dataType
:
std::bool_constant
<
// Base type (no alias needed)
UPstream_base_dataType>::value ||
(
// Or some int 32/64 type to re-map
std::is_integral_v
&& (sizeof(T) == sizeof(int32_t) || sizeof(T) == sizeof(int64_t))
)
>
{
// Is it using the base type? (no alias needed)
static constexpr bool is_base =
UPstream_base_dataType>::value;
using base = std::conditional_t
<
UPstream_base_dataType>::value, // is_base
std::remove_cv_t,
std::conditional_t
<
(
std::is_integral_v
&& (sizeof(T) == sizeof(int32_t) || sizeof(T) == sizeof(int64_t))
),
std::conditional_t
<
(sizeof(T) == sizeof(int32_t)),
std::conditional_t, int32_t, uint32_t>,
std::conditional_t, int64_t, uint64_t>
>,
char // Fallback value (assuming it is contiguous)
>
>;
static constexpr auto datatype_id =
UPstream_base_dataType::datatype_id;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template
void print(const char* name, bool showLimits = true)
{
std::cout
<< "name=\"" << name << "\" sizeof=" << sizeof(T);
if (showLimits)
{
std::cout
<< " max=<";
if constexpr (sizeof(T) == 1)
{
std::cout << int(std::numeric_limits::max());
}
else
{
std::cout << std::numeric_limits::max();
}
std::cout << '>';
}
// A declared or deduced MPI type, or aliased
std::cout
<< " is_mpi=" << UPstream_base_dataType::value
<< " (" << int(UPstream_base_dataType::datatype_id) << ")";
if (UPstream_alias_dataType::value)
{
if (UPstream_alias_dataType::is_base)
{
std::cout<< " is_base";
}
else
{
std::cout<< " is_alias ("
<< int(UPstream_alias_dataType::datatype_id) << ")";
}
}
else
{
std::cout<< " no_alias";
}
std::cout<< '\n';
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
std::cout<< "c++ = " << __cplusplus << '\n';
std::cout<< "machine sizes (and some MPI traits)\n---\n\n";
print("int8_t");
print("uint8_t");
print("int16_t");
print("uint16_t");
print("int32_t");
print("uint32_t");
print("int64_t");
print("uint64_t");
std::cout << '\n';
print("char");
print("unsigned char");
print("short");
print("int");
print("unsigned");
print("long");
print("unsigned long");
print("long long");
std::cout << '\n';
print("std::size_t");
print("std::streamsize");
std::cout << '\n';
print("float");
print("double");
print("long double");
std::cout << "\n---\nEnd\n\n";
return 0;
}
// ************************************************************************* //