Browse Source

Merge pull request #427 from zrax/plFormat_fixes

Fix plFormat for standards-compliant compilers (GCC/Clang)
Adam Johnson 10 years ago
parent
commit
f4ad75978e
  1. 17
      Sources/Plasma/CoreLib/CMakeLists.txt
  2. 4
      Sources/Plasma/CoreLib/plFileSystem.h
  3. 4
      Sources/Plasma/CoreLib/plFormat.cpp
  4. 118
      Sources/Plasma/CoreLib/plFormat.h
  5. 4
      Sources/Plasma/NucleusLib/pnKeyedObject/plUoid.h
  6. 2
      Sources/Plasma/NucleusLib/pnUUID/pnUUID.h

17
Sources/Plasma/CoreLib/CMakeLists.txt

@ -8,17 +8,26 @@ add_definitions(-DPRODUCT_SHORT_NAME="${PRODUCT_SHORT_NAME}")
add_definitions(-DPRODUCT_LONG_NAME="${PRODUCT_LONG_NAME}") add_definitions(-DPRODUCT_LONG_NAME="${PRODUCT_LONG_NAME}")
add_definitions(-DPRODUCT_UUID="${PRODUCT_UUID}") add_definitions(-DPRODUCT_UUID="${PRODUCT_UUID}")
if(NOT WCHAR_BYTES) include(CheckTypeSize)
include(CheckTypeSize)
if(NOT WCHAR_BYTES)
check_type_size("wchar_t" WCHAR_BYTES) check_type_size("wchar_t" WCHAR_BYTES)
if(NOT WCHAR_BYTES) if(NOT WCHAR_BYTES)
message(FATAL_ERROR "Could not determine sizeof(wchar_t)") message(FATAL_ERROR "Could not determine sizeof(wchar_t)")
set(WCHAR_BYTES 0) set(WCHAR_BYTES 0)
endif(NOT WCHAR_BYTES) endif()
endif(NOT WCHAR_BYTES) endif()
add_definitions(-DWCHAR_BYTES=${WCHAR_BYTES}) add_definitions(-DWCHAR_BYTES=${WCHAR_BYTES})
if(NOT SIZEOF_LONG)
check_type_size("long" SIZEOF_LONG)
if(NOT SIZEOF_LONG)
message(FATAL_ERROR "Could not determine sizeof(long)")
set(SIZEOF_LONG 0)
endif()
endif()
add_definitions(-DSIZEOF_LONG=${SIZEOF_LONG})
try_compile(HAVE_CPUID ${PROJECT_BINARY_DIR} try_compile(HAVE_CPUID ${PROJECT_BINARY_DIR}
${PROJECT_SOURCE_DIR}/cmake/check_cpuid.cpp ${PROJECT_SOURCE_DIR}/cmake/check_cpuid.cpp
OUTPUT_VARIABLE OUTPUT) OUTPUT_VARIABLE OUTPUT)

4
Sources/Plasma/CoreLib/plFileSystem.h

@ -227,10 +227,6 @@ inline plFileName operator+(const char *left, const plFileName &right)
{ return left + right.AsString(); } { return left + right.AsString(); }
// Shortcut for use in plFormat
PL_FORMAT_TYPE(const plFileName &)
/** Structure to get information about a file by name. /** Structure to get information about a file by name.
* \sa plFileName * \sa plFileName
*/ */

4
Sources/Plasma/CoreLib/plFormat.cpp

@ -338,7 +338,7 @@ static plStringBuffer<char> _formatChar(const plFormat_Private::FormatSpec &form
#define _PL_FORMAT_IMPL_INT_TYPE(_stype, _utype) \ #define _PL_FORMAT_IMPL_INT_TYPE(_stype, _utype) \
PL_FORMAT_IMPL(_stype) \ PL_FORMAT_IMPL(_stype) \
{ \ { \
/* Note: The use of unsigned here is not a typo -- we only format decimal /* Note: The use of unsigned here is not a typo -- we only format decimal \
values with a sign, so we can convert everything else to unsigned. */ \ values with a sign, so we can convert everything else to unsigned. */ \
switch (format.fDigitClass) { \ switch (format.fDigitClass) { \
case plFormat_Private::kDigitBin: \ case plFormat_Private::kDigitBin: \
@ -388,7 +388,9 @@ _PL_FORMAT_IMPL_INT_TYPE(signed char, unsigned char)
_PL_FORMAT_IMPL_INT_TYPE(short, unsigned short) _PL_FORMAT_IMPL_INT_TYPE(short, unsigned short)
_PL_FORMAT_IMPL_INT_TYPE(int, unsigned) _PL_FORMAT_IMPL_INT_TYPE(int, unsigned)
_PL_FORMAT_IMPL_INT_TYPE(long, unsigned long) _PL_FORMAT_IMPL_INT_TYPE(long, unsigned long)
#if (SIZEOF_LONG == 4)
_PL_FORMAT_IMPL_INT_TYPE(int64_t, uint64_t) _PL_FORMAT_IMPL_INT_TYPE(int64_t, uint64_t)
#endif
PL_FORMAT_IMPL(char) PL_FORMAT_IMPL(char)
{ {

118
Sources/Plasma/CoreLib/plFormat.h

@ -135,30 +135,13 @@ namespace plFormat_Private
} }
/** Declare a formattable type for `plFormat`. /** Declare a formattable type for `plFormat`.
* \note PL_FORMAT_IMPL must only be used in plFormat.h, due to constraints
* on compile-time declaration order imposed by some compilers.
* \sa PL_FORMAT_IMPL() * \sa PL_FORMAT_IMPL()
*/ */
#define PL_FORMAT_TYPE(_type) \ #define PL_FORMAT_TYPE(_type) \
extern plStringBuffer<char> _impl_plFormat_DataHandler( \ extern plStringBuffer<char> _impl_plFormat_DataHandler( \
const plFormat_Private::FormatSpec &format, _type value); \ const plFormat_Private::FormatSpec &format, _type value);
namespace plFormat_Private \
{ \
template <typename... _Args> \
plString _IFormat(_IFormatDataObject &data, _type value, _Args... args) \
{ \
plFormat_Private::FormatSpec format = plFormat_Private::_FetchNextFormat(data); \
data.fOutput.push_back(_impl_plFormat_DataHandler(format, value)); \
return _IFormat(data, args...); \
} \
} \
template <typename... _Args> \
plString plFormat(const char *fmt_str, _type value, _Args... args) \
{ \
plFormat_Private::_IFormatDataObject data; \
data.fFormatStr = fmt_str; \
plFormat_Private::FormatSpec format = plFormat_Private::_FetchNextFormat(data); \
data.fOutput.push_back(_impl_plFormat_DataHandler(format, value)); \
return plFormat_Private::_IFormat(data, args...); \
}
/** Provide the implementation for a formattable type for `plFormat`. /** Provide the implementation for a formattable type for `plFormat`.
* \sa PL_FORMAT_TYPE(), PL_FORMAT_FORWARD() * \sa PL_FORMAT_TYPE(), PL_FORMAT_FORWARD()
@ -191,37 +174,80 @@ namespace plFormat_Private
#define PL_FORMAT_FORWARD(format, fwd_value) \ #define PL_FORMAT_FORWARD(format, fwd_value) \
_impl_plFormat_DataHandler((format), (fwd_value)) _impl_plFormat_DataHandler((format), (fwd_value))
PL_FORMAT_TYPE(char) // ====================================
PL_FORMAT_TYPE(wchar_t) // BEGIN: Formattable type declarations
PL_FORMAT_TYPE(signed char) // ====================================
PL_FORMAT_TYPE(unsigned char)
PL_FORMAT_TYPE(short) PL_FORMAT_TYPE(char)
PL_FORMAT_TYPE(unsigned short) PL_FORMAT_TYPE(wchar_t)
PL_FORMAT_TYPE(int) PL_FORMAT_TYPE(signed char)
PL_FORMAT_TYPE(unsigned) PL_FORMAT_TYPE(unsigned char)
PL_FORMAT_TYPE(long) PL_FORMAT_TYPE(short)
PL_FORMAT_TYPE(unsigned long) PL_FORMAT_TYPE(unsigned short)
PL_FORMAT_TYPE(int64_t) PL_FORMAT_TYPE(int)
PL_FORMAT_TYPE(uint64_t) PL_FORMAT_TYPE(unsigned)
PL_FORMAT_TYPE(const char *) PL_FORMAT_TYPE(long)
PL_FORMAT_TYPE(const wchar_t *) PL_FORMAT_TYPE(unsigned long)
PL_FORMAT_TYPE(const plString &) #if (SIZEOF_LONG == 4)
PL_FORMAT_TYPE(int64_t)
// TODO: Remove these when they're no longer needed PL_FORMAT_TYPE(uint64_t)
PL_FORMAT_TYPE(const std::string &) #endif
PL_FORMAT_TYPE(const std::wstring &) PL_FORMAT_TYPE(const char *)
PL_FORMAT_TYPE(const wchar_t *)
// TODO: Implement floating point types (float, double). They're harder PL_FORMAT_TYPE(const plString &)
// than the others, so I'll get around to them later >.>
// Shortcut for plFileName
// Formats as "true" or "false", following normal string formatting rules. PL_FORMAT_TYPE(const class plFileName &)
// To use other formats, don't pass us a bool directly...
PL_FORMAT_TYPE(bool) // TODO: Remove these when they're no longer needed
PL_FORMAT_TYPE(const std::string &)
PL_FORMAT_TYPE(const std::wstring &)
// TODO: Implement floating point types (float, double). They're harder
// than the others, so I'll get around to them later >.>
// Formats as "true" or "false", following normal string formatting rules.
// To use other formats, don't pass us a bool directly...
PL_FORMAT_TYPE(bool)
// Formats for plUoid
PL_FORMAT_TYPE(const class plLocation &)
PL_FORMAT_TYPE(const class plUoid &)
// Format for plUUID
PL_FORMAT_TYPE(const class plUUID &)
// ==================================
// END: Formattable type declarations
// ==================================
// NOTE: Added in order to work properly in GCC/Clang; all PL_FORMAT_TYPE
// declarations MUST be above this line.
#undef PL_FORMAT_TYPE
namespace plFormat_Private namespace plFormat_Private
{ {
// End of the chain -- emits the last piece (if any) and builds the final string // End of the chain -- emits the last piece (if any) and builds the final string
plString _IFormat(_IFormatDataObject &data); plString _IFormat(_IFormatDataObject &data);
// Internal plFormat implementation which carries over the pieces formatted so far
template <typename _Type, typename... _Args>
plString _IFormat(_IFormatDataObject &data, _Type value, _Args... args)
{
plFormat_Private::FormatSpec format = plFormat_Private::_FetchNextFormat(data);
data.fOutput.push_back(_impl_plFormat_DataHandler(format, value));
return _IFormat(data, args...);
}
}
template <typename _Type, typename... _Args>
plString plFormat(const char *fmt_str, _Type value, _Args... args)
{
plFormat_Private::_IFormatDataObject data;
data.fFormatStr = fmt_str;
plFormat_Private::FormatSpec format = plFormat_Private::_FetchNextFormat(data);
data.fOutput.push_back(_impl_plFormat_DataHandler(format, value));
return plFormat_Private::_IFormat(data, args...);
} }
#endif // plFormat_Defined #endif // plFormat_Defined

4
Sources/Plasma/NucleusLib/pnKeyedObject/plUoid.h

@ -144,8 +144,6 @@ public:
static const plLocation kInvalidLoc; static const plLocation kInvalidLoc;
}; };
PL_FORMAT_TYPE(const plLocation &)
//// plUoid ////////////////////////////////////////////////////////////////// //// plUoid //////////////////////////////////////////////////////////////////
class plUoid class plUoid
@ -200,6 +198,4 @@ protected:
plLoadMask fLoadMask; plLoadMask fLoadMask;
}; };
PL_FORMAT_TYPE(const plUoid &)
#endif // plUoid_h_inc #endif // plUoid_h_inc

2
Sources/Plasma/NucleusLib/pnUUID/pnUUID.h

@ -96,6 +96,4 @@ public:
static plUUID Generate(); static plUUID Generate();
}; };
PL_FORMAT_TYPE(const plUUID &)
#endif // pnUUID_h_inc #endif // pnUUID_h_inc

Loading…
Cancel
Save