Commit 09281516 authored by Sebastian Eibl's avatar Sebastian Eibl
Browse files

Merge branch 'ifdef' into 'master'

Eliminate most compiler-specific workarounds

See merge request walberla/walberla!387
parents 73e67f6e 72ca3f72
......@@ -225,16 +225,21 @@ else()
endif()
mark_as_advanced ( WALBERLA_CXX_COMPILER_IS_CLANG )
# Check for Cray compiler
if( CMAKE_CXX_COMPILER_ID MATCHES Cray )
option ( WALBERLA_CXX_COMPILER_IS_CRAY "Use Cray compiler" ON )
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.4)
message( FATAL_ERROR "Insufficient Cray Compiler Environment version" )
endif()
else()
option ( WALBERLA_CXX_COMPILER_IS_CRAY "Use Cray compiler" OFF )
endif()
mark_as_advanced ( WALBERLA_CXX_COMPILER_IS_CRAY )
if( CMAKE_CXX_COMPILER MATCHES "pgc\\+\\+" OR CMAKE_CXX_COMPILER_ARG1 MATCHES "pgc\\+\\+" )
option ( WALBERLA_CXX_COMPILER_IS_PGI "Use PGI compiler" ON )
else()
option ( WALBERLA_CXX_COMPILER_IS_PGI "Use PGI compiler" OFF )
endif()
mark_as_advanced ( WALBERLA_CXX_COMPILER_IS_PGI )
# Check for MPI wrapper
get_filename_component( CXX_COMPILER_WITHOUT_PATH ${CMAKE_CXX_COMPILER} NAME )
if( CXX_COMPILER_WITHOUT_PATH MATCHES "mpi" OR CMAKE_CXX_COMPILER_ARG1 MATCHES "mpi" )
......@@ -333,6 +338,21 @@ if( WALBERLA_CXX_COMPILER_IS_CRAY )
add_flag ( CMAKE_CXX_FLAGS "-DSQLITE_HAVE_ISNAN" ) # SQLite will not work correctly with the -ffast-math option of GCC.
endif()
# Silences compiler and linker warnings and information with the PGI compiler
if( WALBERLA_CXX_COMPILER_IS_PGI )
add_flag ( CMAKE_CXX_FLAGS "--display_error_number" )
add_flag ( CMAKE_C_FLAGS "--display_error_number" )
if( CMAKE_VERSION VERSION_LESS "3.19" )
# https://github.com/Kitware/CMake/commit/52eee1938919deb59cc2b51d44f365f0d9a418e5
set( CMAKE_CXX${CMAKE_CXX_STANDARD}_STANDARD_COMPILE_OPTION "--c++${CMAKE_CXX_STANDARD}" )
endif()
add_flag ( CMAKE_CXX_FLAGS "--diag_suppress=1" ) # last line of file ends without a newline
add_flag ( CMAKE_CXX_FLAGS "--diag_suppress=111" ) # statement is unreachable
add_flag ( CMAKE_C_FLAGS "--diag_suppress=111" ) # statement is unreachable
add_flag ( CMAKE_C_FLAGS "--diag_suppress=550" ) # variable [...] was set but never used
add_flag ( CMAKE_C_FLAGS "--diag_suppress=191" ) # type qualifier is meaningless on cast type
endif()
# architecture optimization
if( WALBERLA_OPTIMIZE_FOR_LOCALHOST )
if( WALBERLA_CXX_COMPILER_IS_GNU OR WALBERLA_CXX_COMPILER_IS_INTEL OR WALBERLA_CXX_COMPILER_IS_CLANG )
......@@ -690,8 +710,14 @@ endif( Boost_FOUND )
##
############################################################################################################################
if ( NOT WIN32 )
add_flag( CMAKE_CXX_FLAGS "-pthread" )
set( THREADS_PREFER_PTHREAD_FLAG TRUE )
find_package(Threads)
if ( Threads_FOUND )
if( CMAKE_USE_PTHREADS_INIT )
add_flag( CMAKE_CXX_FLAGS "-pthread" )
else()
add_flag( CMAKE_CXX_FLAGS "${CMAKE_THREAD_LIBS_INIT}" )
endif()
endif()
......@@ -975,10 +1001,7 @@ endif()
option ( WALBERLA_THREAD_SAFE_LOGGING "Enables/Disables thread-safe logging" ON )
if ( WALBERLA_BUILD_WITH_OPENMP )
if ( WALBERLA_CXX_COMPILER_IS_INTEL AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "16.0.3" )
add_flag ( CMAKE_C_FLAGS "-openmp" )
add_flag ( CMAKE_CXX_FLAGS "-openmp" )
elseif ( WALBERLA_CXX_COMPILER_IS_NEC )
if ( WALBERLA_CXX_COMPILER_IS_NEC )
add_flag ( CMAKE_C_FLAGS "-Popenmp" )
add_flag ( CMAKE_CXX_FLAGS "-Popenmp" )
else()
......@@ -1089,31 +1112,7 @@ endif()
##
############################################################################################################################
if ( WALBERLA_BUILD_WITH_LTO )
if( WALBERLA_CXX_COMPILER_IS_INTEL )
add_flag( CMAKE_CXX_FLAGS_RELEASE "-ip -ipo3" )
add_flag( CMAKE_C_FLAGS_RELEASE "-ip -ipo3" )
endif()
if ( CMAKE_COMPILER_IS_GNUCXX )
add_flag ( CMAKE_C_FLAGS_RELEASE "-flto=3" )
add_flag ( CMAKE_CXX_FLAGS_RELEASE "-flto=3" )
add_flag ( CMAKE_EXE_LINKER_FLAGS "-fuse-linker-plugin" )
endif ( )
if( WALBERLA_CXX_COMPILER_IS_MSVC )
add_flag ( CMAKE_CXX_FLAGS_RELEASE "/GL" )
add_flag ( CMAKE_EXE_LINKER_FLAGS_RELEASE "/LTCG" )
add_flag ( CMAKE_SHARED_LINKER_FLAGS_RELEASE "/LTCG" )
add_flag ( CMAKE_MODULE_LINKER_FLAGS_RELEASE "/LTCG" )
endif ( )
if( WALBERLA_CXX_COMPILER_IS_IBM )
add_flag ( CMAKE_C_FLAGS_RELEASE "-qipa" )
add_flag ( CMAKE_CXX_FLAGS_RELEASE "-qipa" )
add_flag ( CMAKE_EXE_LINKER_FLAGS "-qipa" )
endif( )
set( CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE )
endif ( )
############################################################################################################################
......
......@@ -36,7 +36,7 @@ namespace lbm
namespace internal_boundary_contact
{
static FUNC_PREFIX void contact_angle_treatment(uint8_t* RESTRICT const _data_indexVector, double* RESTRICT _data_phase,
static FUNC_PREFIX void contact_angle_treatment(uint8_t* WALBERLA_RESTRICT const _data_indexVector, double* WALBERLA_RESTRICT _data_phase,
int64_t const _stride_phase_0, int64_t const _stride_phase_1,
int64_t const _stride_phase_2, int64_t indexVectorSize, double alpha)
{
......@@ -58,8 +58,8 @@ static FUNC_PREFIX void contact_angle_treatment(uint8_t* RESTRICT const _data_in
const double a = cos(alpha);
const double W = 5;
double* RESTRICT _phase_wall = _data_phase + _stride_phase_1 * y + _stride_phase_2 * z;
double* RESTRICT _phase_interior = _data_phase + _stride_phase_1 * y1 + _stride_phase_2 * z1;
double* WALBERLA_RESTRICT _phase_wall = _data_phase + _stride_phase_1 * y + _stride_phase_2 * z;
double* WALBERLA_RESTRICT _phase_interior = _data_phase + _stride_phase_1 * y1 + _stride_phase_2 * z1;
if (h < 0.001) { _phase_wall[_stride_phase_0 * x] = 1.0; }
else if (a > 1e-8 || a < -1e-8)
{
......@@ -98,7 +98,7 @@ void contact::run(IBlock* block, IndexVectors::Type type)
auto& alpha = this->alpha_;
WALBERLA_ASSERT_GREATER_EQUAL(0, -int_c(phaseField->nrOfGhostLayers()))
double* RESTRICT _data_phase = phaseField->dataAt(0, 0, 0, 0);
double* WALBERLA_RESTRICT _data_phase = phaseField->dataAt(0, 0, 0, 0);
const auto _stride_pdfs_0 = int64_t(phaseField->xStride());
const auto _stride_pdfs_1 = int64_t(phaseField->yStride());
const auto _stride_pdfs_2 = int64_t(phaseField->zStride());
......
......@@ -31,14 +31,6 @@
#include <set>
#include <vector>
#ifdef __GNUC__
# define RESTRICT __restrict__
#elif _MSC_VER
# define RESTRICT __restrict
#else
# define RESTRICT
#endif
namespace walberla
{
namespace lbm
......
......@@ -41,25 +41,25 @@ namespace lbm
namespace internal_boundary_contact
{
static FUNC_PREFIX void contact_angle_treatment(uint8_t* RESTRICT const _data_indexVector, double* RESTRICT _data_phase,
static FUNC_PREFIX void contact_angle_treatment(uint8_t* WALBERLA_RESTRICT const _data_indexVector, double* WALBERLA_RESTRICT _data_phase,
int64_t const _stride_phase_0, int64_t const _stride_phase_1,
int64_t const _stride_phase_2, int64_t indexVectorSize, double alpha)
{
if (blockDim.x * blockIdx.x + threadIdx.x < indexVectorSize)
{
uint8_t* RESTRICT _data_indexVector_10 = _data_indexVector;
uint8_t* WALBERLA_RESTRICT _data_indexVector_10 = _data_indexVector;
const int32_t x = *((int32_t*) (&_data_indexVector_10[24 * blockDim.x * blockIdx.x + 24 * threadIdx.x]));
uint8_t* RESTRICT _data_indexVector_14 = _data_indexVector + 4;
uint8_t* WALBERLA_RESTRICT _data_indexVector_14 = _data_indexVector + 4;
const int32_t y = *((int32_t*) (&_data_indexVector_14[24 * blockDim.x * blockIdx.x + 24 * threadIdx.x]));
uint8_t* RESTRICT _data_indexVector_18 = _data_indexVector + 8;
uint8_t* WALBERLA_RESTRICT _data_indexVector_18 = _data_indexVector + 8;
const int32_t z = *((int32_t*) (&_data_indexVector_18[24 * blockDim.x * blockIdx.x + 24 * threadIdx.x]));
uint8_t* RESTRICT _data_indexVector_112 = _data_indexVector + 12;
uint8_t* WALBERLA_RESTRICT _data_indexVector_112 = _data_indexVector + 12;
const int32_t nx = *((int32_t*) (&_data_indexVector_112[24 * blockDim.x * blockIdx.x + 24 * threadIdx.x]));
const int32_t x1 = x + nx;
uint8_t* RESTRICT _data_indexVector_116 = _data_indexVector + 16;
uint8_t* WALBERLA_RESTRICT _data_indexVector_116 = _data_indexVector + 16;
const int32_t ny = *((int32_t*) (&_data_indexVector_116[24 * blockDim.x * blockIdx.x + 24 * threadIdx.x]));
const int32_t y1 = y + ny;
uint8_t* RESTRICT _data_indexVector_200 = _data_indexVector + 20;
uint8_t* WALBERLA_RESTRICT _data_indexVector_200 = _data_indexVector + 20;
const int32_t nz = *((int32_t*) (&_data_indexVector_200[24 * blockDim.x * blockIdx.x + 24 * threadIdx.x]));
const int32_t z1 = z + nz;
......@@ -67,8 +67,8 @@ static FUNC_PREFIX void contact_angle_treatment(uint8_t* RESTRICT const _data_in
const double a = cos(alpha);
const double W = 5;
double* RESTRICT _phase_wall = _data_phase + _stride_phase_1 * y + _stride_phase_2 * z;
double* RESTRICT _phase_interior = _data_phase + _stride_phase_1 * y1 + _stride_phase_2 * z1;
double* WALBERLA_RESTRICT _phase_wall = _data_phase + _stride_phase_1 * y + _stride_phase_2 * z;
double* WALBERLA_RESTRICT _phase_interior = _data_phase + _stride_phase_1 * y1 + _stride_phase_2 * z1;
if (h < 0.001) { _phase_wall[_stride_phase_0 * x] = 1.0; }
else if (a > 1e-8 || a < -1e-8)
{
......@@ -107,7 +107,7 @@ void contact::run(IBlock* block, IndexVectors::Type type, cudaStream_t stream)
auto& alpha = this->alpha_;
WALBERLA_ASSERT_GREATER_EQUAL(0, -int_c(phaseField->nrOfGhostLayers()))
double* RESTRICT _data_phase = phaseField->dataAt(0, 0, 0, 0);
double* WALBERLA_RESTRICT _data_phase = phaseField->dataAt(0, 0, 0, 0);
const auto _stride_pdfs_0 = int64_t(phaseField->xStride());
const auto _stride_pdfs_1 = int64_t(phaseField->yStride());
const auto _stride_pdfs_2 = int64_t(phaseField->zStride());
......
......@@ -32,14 +32,6 @@
#include <set>
#include <vector>
#ifdef __GNUC__
# define RESTRICT __restrict__
#elif _MSC_VER
# define RESTRICT __restrict
#else
# define RESTRICT
#endif
namespace walberla
{
namespace lbm
......
......@@ -1661,7 +1661,7 @@ bool BlockForest::determineBlockTargetLevels( bool & additionalRefreshCycleRequi
minTargetLevels[id] = minTargetLevel;
}
}
#ifndef NDEBUF
#ifndef NDEBUG
else
{
WALBERLA_ASSERT_LESS_EQUAL( minTargetLevel, level + uint_t(1) );
......
......@@ -135,11 +135,9 @@ void BlockID::toByteArray( std::vector< uint8_t >& array, const uint_t offset, c
#else
#ifdef WALBERLA_CXX_COMPILER_IS_MSVC
namespace { char dummy; } // disable MSVC warning LNK4221: This object file does not define any previously
// undefined public symbols, so it will not be used by any link operation that
// consumes this library
#endif
namespace internal {
char dummy; // silence linker warning about object file with no symbols
}
#endif
......
......@@ -35,34 +35,8 @@ namespace walberla{
class NonCreateable {
#ifndef _MSC_VER
// non-MSVC-Build
private:
NonCreateable();
~NonCreateable();
NonCreateable(const NonCreateable&);
NonCreateable& operator=(const NonCreateable&);
#else
// MSVC-Build (eliminating warning C4624)
private:
NonCreateable();
NonCreateable(const NonCreateable&);
NonCreateable& operator=(const NonCreateable&);
protected:
~NonCreateable();
#endif
public:
NonCreateable() = delete;
};
......
......@@ -21,16 +21,15 @@
#pragma once
#if (( defined WALBERLA_CXX_COMPILER_IS_CLANG ) && ( __clang_major__ >=4 ) ) \
|| (( defined WALBERLA_CXX_COMPILER_IS_GNU ) && ( __GNUC__ >= 5 ) )
#if defined(WALBERLA_CXX_COMPILER_IS_CLANG) || defined(WALBERLA_CXX_COMPILER_IS_GNU)
# define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
#else
# define ATTRIBUTE_NO_SANITIZE_ADDRESS
#endif
#if ( ( defined WALBERLA_CXX_COMPILER_IS_GNU ) && ( __GNUC__ >= 5 ) )
#if defined(WALBERLA_CXX_COMPILER_IS_GNU)
# define ATTRIBUTE_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined))
#elif (( defined WALBERLA_CXX_COMPILER_IS_CLANG ) && ( __clang_major__ >= 4 ) )
#elif defined(WALBERLA_CXX_COMPILER_IS_CLANG)
# define ATTRIBUTE_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined")))
#else
# define ATTRIBUTE_NO_SANITIZE_UNDEFINED
......
......@@ -22,36 +22,13 @@
#include "Sleep.h"
#include "waLBerlaDefinitions.h"
#ifdef WALBERLA_CXX_COMPILER_IS_MSVC
#include <windows.h>
#include <thread>
namespace walberla {
void sleep( uint_t seconds )
{
::Sleep( static_cast<DWORD>( uint_t(1000) * seconds ) );
}
void sleep( uint_t seconds )
{
std::this_thread::sleep_for(std::chrono::seconds(static_cast<int>(seconds)));
}
#else
#ifdef WALBERLA_CXX_COMPILER_IS_IBM
#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE
#endif
#endif
#include <unistd.h>
namespace walberla {
void sleep( uint_t seconds )
{
::sleep( static_cast<unsigned int>(seconds) );
}
}
#endif
\ No newline at end of file
//======================================================================================================================
//
// This file is part of waLBerla. waLBerla 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.
//
// waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
//
//! \file Template.h
//! \ingroup core
//! \author Klaus Iglberger
//! \author Sebastian Eibl <sebastian.eibl@fau.de>
//
//======================================================================================================================
#pragma once
//*************************************************************************************************
/*! \cond internal */
/*!\brief Compiler specific patch for nested template disambiguation.
* \ingroup util
*
* The WALBERLA_TEMPLATE is a patch for the Microsoft Visual C++ compiler that does not correctly
* parse definitions of nested templates of the following form:
\code
template< typename T >
class Alloc {
public:
...
template< typename Other >
class rebind {
public:
typedef Alloc<Other> other;
};
...
};
typedef Alloc<int> AI;
typedef AI::template rebind<double>::other Other; // Compilation error with Visual C++
\endcode
* In order to circumvent this compilation error, the WALBERLA_TEMPLATE macro should be used instead
* the \a template keyword:
\code
...
typedef AI::WALBERLA_TEMPLATE rebind<double>::other Other; // No compilation errors
\endcode
*/
#if defined(_MSC_VER)
# define WALBERLA_TEMPLATE
#else
# define WALBERLA_TEMPLATE template
#endif
/*! \endcond */
//*************************************************************************************************
......@@ -30,12 +30,6 @@
#include <cmath>
#include <core/DataTypes.h>
// Disable false warnings in GCC 5
#if (defined __GNUC__) && (__GNUC__ == 5) && (__GNUC_MINOR__ == 1)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-variable"
#endif
namespace walberla
{
namespace math
......
......@@ -31,9 +31,7 @@
# pragma warning( disable : 4706 )
#elif ( defined WALBERLA_CXX_COMPILER_IS_GNU ) || ( defined WALBERLA_CXX_COMPILER_IS_CLANG )
# pragma GCC diagnostic push
# if !( ( __clang_major__ == 3 ) && ( __clang_minor__ <= 4 ) )
# pragma GCC diagnostic ignored "-Wpragmas"
# endif
# pragma GCC diagnostic ignored "-Wpragmas"
# pragma GCC diagnostic ignored "-Wsign-conversion"
# pragma GCC diagnostic ignored "-Wconversion"
# pragma GCC diagnostic ignored "-Wshorten-64-to-32"
......
......@@ -49,11 +49,5 @@ template<> uint_t uintMSBPosition< uint64_t >( uint64_t value ) { // for the doc
return ( i != 0 ) ? (8 + msbLookupTable[i]) : msbLookupTable[value];
}
#ifndef WALBERLA_CXX_COMPILER_IS_MSVC
const uint_t int_ld<1>::exp;
#endif
} // namespace math
} // namespace walberla
......@@ -222,8 +222,8 @@ struct leastUnsignedInteger
};
/// \cond internal
static const uint_t UINT_BITS = static_cast< uint_t >( std::numeric_limits< uint_t >::digits );
static const uint_t UINT_BYTES = static_cast< uint_t >( std::numeric_limits< uint_t >::digits ) >> 3;
static constexpr uint_t UINT_BITS = static_cast< uint_t >( std::numeric_limits< uint_t >::digits );
static constexpr uint_t UINT_BYTES = static_cast< uint_t >( std::numeric_limits< uint_t >::digits ) >> 3;
static_assert( !(UINT_BITS & (UINT_BITS - 1)), "Type \"uint_t\" must consist of 2^x Bits!" ); // power of two
......@@ -231,18 +231,17 @@ template< int N >
struct int_ld
{
static_assert( N >= 1 && !(N & (N - 1)), "Calculating log_2(N) -> \"N\" must be a power of two!" );
static const uint_t exp = 1 + int_ld< (N >> 1) >::exp;
static constexpr uint_t exp = 1 + int_ld< (N >> 1) >::exp;
static_assert( exp > 0 );
};
template< int N > const uint_t int_ld<N>::exp;
template<>
struct int_ld<1>
{
static const uint_t exp = 0;
static constexpr uint_t exp = 0;
};
static const uint_t UINT_BITS_LD = int_ld< std::numeric_limits< uint_t >::digits >::exp;
static constexpr uint_t UINT_BITS_LD = int_ld< std::numeric_limits< uint_t >::digits >::exp;
/// \endcond
} // namespace math
......
......@@ -143,13 +143,6 @@ void sendContainer( GenericSendBuffer<T,G> & buf, const Cont & container )
}
#ifdef WALBERLA_CXX_COMPILER_IS_GNU
#if __GNUC__ == 4 && __GNUC_MINOR__ == 9 || __GNUC__ == 6
#pragma GCC push_options
#pragma GCC optimize(2)
#endif
#endif
template< typename T, // Element type of RecvBuffer
typename Cont> // Container
void recvContainer( GenericRecvBuffer<T> & buf, Cont & container )
......@@ -162,12 +155,6 @@ void recvContainer( GenericRecvBuffer<T> & buf, Cont & container )
buf >> *it;
}
#ifdef WALBERLA_CXX_COMPILER_IS_GNU
#if __GNUC__ == 4 && __GNUC_MINOR__ == 9 || __GNUC__ == 6
#pragma GCC pop_options
#endif
#endif
template< typename T, // Element type of SendBuffer
......
......@@ -149,7 +149,7 @@
#ifdef _OPENMP
#ifdef WALBERLA_CXX_COMPILER_IS_MSVC
#if (defined(_MSC_VER) && _MSC_VER < 1926)
#define WALBERLA_FOR_ALL_CELLS_XYZ_OMP( field, omp, CODE ) \
{ WALBERLA_ASSERT_NOT_NULLPTR_1( (field) ); \
......@@ -875,7 +875,7 @@
} \
} }
#else // == not WALBERLA_CXX_COMPILER_IS_MSVC
#else // == MSVC >= 2019 16.6 or not MSVC
#define WALBERLA_FOR_ALL_CELLS_XYZ_OMP( field, omp, CODE ) \
{ WALBERLA_ASSERT_NOT_NULLPTR_1( (field) ); \
......
......@@ -27,9 +27,7 @@
# pragma warning( disable : 4706 )
#elif ( defined WALBERLA_CXX_COMPILER_IS_GNU ) || ( defined WALBERLA_CXX_COMPILER_IS_CLANG )
# pragma GCC diagnostic push
# if !( ( __clang_major__ == 3 ) && ( __clang_minor__ <= 4 ) )
# pragma GCC diagnostic ignored "-Wpragmas"
# endif
# pragma GCC diagnostic ignored "-Wpragmas"
# pragma GCC diagnostic ignored "-Wsign-conversion"
# pragma GCC diagnostic ignored "-Wconversion"
# pragma GCC diagnostic ignored "-Wshorten-64-to-32"
......
......@@ -28,23 +28,6 @@
#ifdef WALBERLA_BUILD_WITH_PYTHON // macro defined in waLBerlaDefinitions.h
#ifdef _MSC_VER
#pragma warning ( push, 3 )
#pragma warning ( disable: 4244 4275 4800 4251 4267 )
#ifndef HAVE_ROUND
#define HAVE_ROUND 1
#define __CREATED_HAVE_ROUND
#endif
#endif
#include "pybind11/pybind11.h"
#ifdef _MSC_VER
#ifdef __CREATED_HAVE_ROUND
#undef HAVE_ROUND
#undef __CREATED_HAVE_ROUND
#endif
#pragma warning ( pop )
#endif
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment