From 9f0cb1327bad28ca727f1181baeba99cc1f3b7d9 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sat, 8 Aug 2015 13:25:18 -1000 Subject: [PATCH] Added some SFINAE parameters for smart IO templates --- atdna/main.cpp | 67 ++---------------- extern/yaml/CMakeLists.txt | 13 +--- include/Athena/DNAYaml.hpp | 112 +++++++++++++++++++++++++++++++ include/Athena/IStreamReader.hpp | 90 +++++++++++++++++++++++++ include/Athena/IStreamWriter.hpp | 38 +++++++++++ 5 files changed, 249 insertions(+), 71 deletions(-) diff --git a/atdna/main.cpp b/atdna/main.cpp index 52fe843..ad0c05f 100644 --- a/atdna/main.cpp +++ b/atdna/main.cpp @@ -718,27 +718,9 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor fileOut << " /* " << fieldName << " */\n"; if (!p) - { - fileOut << " " << fieldName << ".clear();\n" - " " << fieldName << ".reserve(" << sizeExpr << ");\n"; - if (isDNAType) - fileOut << " for (size_t i=0 ; i<(" << sizeExpr << ") ; ++i)\n" - " {\n" - " " << fieldName << ".emplace_back();\n" - " " << fieldName << ".back()." << ioOp << "\n" - " }\n"; - else - fileOut << " for (size_t i=0 ; i<(" << sizeExpr << ") ; ++i)\n" - " " << fieldName << ".push_back(" << ioOp << ");\n"; - } + fileOut << " " ATHENA_DNA_READER ".enumerate(" << fieldName << ", " << sizeExpr << ");\n"; else - { - fileOut << " for (const auto& elem : " << fieldName << ")\n"; - if (isDNAType) - fileOut << " elem." << ioOp << "\n"; - else - fileOut << " " << ioOp << "\n"; - } + fileOut << " " ATHENA_DNA_WRITER ".enumerate(" << fieldName << ");\n"; } else if (!tsDecl->getName().compare("Buffer")) @@ -1357,42 +1339,9 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor fileOut << " /* " << fieldName << " */\n"; if (!p) - { - fileOut << " " << fieldName << ".clear();\n" - " " << fieldName << ".reserve(" << sizeExpr << ");\n" - " " ATHENA_YAML_READER ".enterSubVector(\"" << fieldNameBare << "\");\n"; - if (isDNAType) - fileOut << " for (size_t i=0 ; i<(" << sizeExpr << ") ; ++i)\n" - " {\n" - " " << fieldName << ".emplace_back();\n" - " " ATHENA_YAML_READER ".enterSubRecord(nullptr);\n" - " " << fieldName << ".back()." << ioOp << "\n" - " " ATHENA_YAML_READER ".leaveSubRecord();\n" - " }\n"; - else - fileOut << " for (size_t i=0 ; i<(" << sizeExpr << ") ; ++i)\n" - " " << fieldName << ".push_back(" << ioOp << ");\n"; - fileOut << " " ATHENA_YAML_READER ".leaveSubVector();\n"; - } + fileOut << " " ATHENA_YAML_READER ".enumerate(\"" << fieldNameBare << "\", " << fieldName << ", " << sizeExpr << ");\n"; else - { - fileOut << " " ATHENA_YAML_WRITER ".enterSubVector(\"" << fieldNameBare << "\");\n"; - if (isDNAType) - { - fileOut << " for (const auto& elem : " << fieldName << ")\n" - " {\n" - " " ATHENA_YAML_WRITER ".enterSubRecord(nullptr);\n" - " elem." << ioOp << "\n" - " " ATHENA_YAML_WRITER ".leaveSubRecord();\n" - " }\n"; - } - else - { - fileOut << " for (const auto& elem : " << fieldName << ")\n" - " " << ioOp << "\n"; - } - fileOut << " " ATHENA_YAML_WRITER ".leaveSubVector();\n"; - } + fileOut << " " ATHENA_YAML_WRITER ".enumerate(\"" << fieldNameBare << "\", " << fieldName << ");\n"; } else if (!tsDecl->getName().compare("Buffer")) @@ -1496,16 +1445,12 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor if (!p) { fileOut << " /* " << fieldName << " */\n" - " " ATHENA_YAML_READER ".enterSubRecord(\"" << fieldNameBare << "\");\n" - " " << fieldName << ".fromYAML(" ATHENA_YAML_READER ");\n" - " " ATHENA_YAML_READER ".leaveSubRecord();\n"; + " " ATHENA_YAML_READER ".enumerate(\"" << fieldNameBare << "\", " << fieldName << ");\n"; } else { fileOut << " /* " << fieldName << " */\n" - " " ATHENA_YAML_WRITER ".enterSubRecord(\"" << fieldNameBare << "\");\n" - " " << fieldName << ".toYAML(" ATHENA_YAML_WRITER ");\n" - " " ATHENA_YAML_WRITER ".leaveSubRecord();\n"; + " " ATHENA_YAML_WRITER ".enumerate(\"" << fieldNameBare << "\", " << fieldName << ");\n"; } break; } diff --git a/extern/yaml/CMakeLists.txt b/extern/yaml/CMakeLists.txt index e8cd4f6..ad50d21 100644 --- a/extern/yaml/CMakeLists.txt +++ b/extern/yaml/CMakeLists.txt @@ -1,8 +1,3 @@ -# Minimal CMake project for building a static library under Windows. - -cmake_minimum_required(VERSION 2.8) -project(yaml C) - set(YAML_VERSION_MAJOR 0) set(YAML_VERSION_MINOR 1) set(YAML_VERSION_PATCH 6) @@ -12,10 +7,8 @@ file(GLOB SRC src/*.c) include_directories(include win32) add_definitions(-DYAML_DECLARE_STATIC) -add_library(yaml STATIC ${SRC} include/yaml.h) +add_library(AthenaLibYaml STATIC ${SRC} include/yaml.h) set(YAML_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE PATH "YAML include path" FORCE) -if(WIN32 AND NOT UNIX) - install(DIRECTORY include/ DESTINATION include COMPONENT yaml) - install(TARGETS yaml DESTINATION lib COMPONENT yaml) -endif() +install(DIRECTORY include/ DESTINATION include/Athena COMPONENT yaml) +install(TARGETS AthenaLibYaml DESTINATION lib COMPONENT yaml) diff --git a/include/Athena/DNAYaml.hpp b/include/Athena/DNAYaml.hpp index 2bec2d2..adc4927 100644 --- a/include/Athena/DNAYaml.hpp +++ b/include/Athena/DNAYaml.hpp @@ -434,6 +434,14 @@ public: m_subStack.pop_back(); } + template + void enumerate(const char* name, T& record) + { + enterSubRecord(name); + record.fromYAML(*this); + leaveSubRecord(); + } + void enterSubVector(const char* name) { YAMLNode* curSub = m_subStack.back(); @@ -458,6 +466,58 @@ public: } } + template + void enumerate(const char* name, std::vector& vector, size_t count, + typename std::enable_if::value && + !std::is_same::value && + !std::is_same::value && + !std::is_same::value>::type* = 0) + { + vector.clear(); + vector.reserve(count); + enterSubVector(name); + for (int i=0 ; i + void enumerate(const char* name, std::vector& vector, size_t count, + typename std::enable_if::value || + std::is_same::value || + std::is_same::value || + std::is_same::value>::type* = 0) + { + vector.clear(); + vector.reserve(count); + enterSubVector(name); + for (int i=0 ; i(name)); + leaveSubVector(); + } + + template + void enumerate(const char* name, std::vector& vector, size_t count, + std::function readf) + { + vector.clear(); + vector.reserve(count); + enterSubVector(name); + for (int i=0 ; i RETURNTYPE readVal(const char* name) { @@ -621,6 +681,14 @@ public: } } + template + void enumerate(const char* name, T& record) + { + enterSubRecord(name); + record.toYAML(*this); + leaveSubRecord(); + } + void enterSubVector(const char* name) { YAMLNode* curSub = m_subStack.back(); @@ -641,6 +709,50 @@ public: m_subStack.pop_back(); } + template + void enumerate(const char* name, const std::vector& vector, + typename std::enable_if::value && + !std::is_same::value && + !std::is_same::value && + !std::is_same::value>::type* = 0) + { + enterSubVector(name); + for (const T& item : vector) + { + enterSubRecord(nullptr); + item.toYAML(*this); + leaveSubRecord(); + } + leaveSubVector(); + } + + template + void enumerate(const char* name, const std::vector& vector, + typename std::enable_if::value || + std::is_same::value || + std::is_same::value || + std::is_same::value>::type* = 0) + { + enterSubVector(name); + for (T item : vector) + writeVal(nullptr, item); + leaveSubVector(); + } + + template + void enumerate(const char* name, const std::vector& vector, + std::function writef) + { + enterSubVector(name); + for (const T& item : vector) + { + enterSubRecord(nullptr); + writef(*this, item); + leaveSubRecord(); + } + leaveSubVector(); + } + bool finish(yaml_emitter_t* docOut) { yaml_event_t event = {YAML_DOCUMENT_START_EVENT}; diff --git a/include/Athena/IStreamReader.hpp b/include/Athena/IStreamReader.hpp index b1e0d84..77ce512 100644 --- a/include/Athena/IStreamReader.hpp +++ b/include/Athena/IStreamReader.hpp @@ -3,6 +3,7 @@ #include #include +#include #include "IStream.hpp" namespace Athena @@ -78,12 +79,18 @@ public: * \return Int8 The value at the current position */ inline atInt8 readByte() {atInt8 val; readUBytesToBuf(&val, 1); return val;} + template + inline atInt8 readVal(typename std::enable_if::value>::type* = 0) + {return readByte();} /*! \brief Reads a byte at the current position and advances the current position * * \return Uint8 The value at the current position */ inline atUint8 readUByte() {return readByte();} + template + inline atUint8 readVal(typename std::enable_if::value>::type* = 0) + {return readUByte();} /*! \brief Reads a byte at the current position and advances the current position. * @@ -124,6 +131,9 @@ public: readUBytesToBuf(&val, 2); return m_endian == BigEndian ? utility::BigInt16(val) : utility::LittleInt16(val); } + template + inline atInt16 readVal(typename std::enable_if::value>::type* = 0) + {return readInt16();} /*! \brief Reads a Uint16 and swaps to proper endianness depending on platform * and Stream settings, and advances the current position @@ -135,6 +145,9 @@ public: */ inline atUint16 readUint16() {return readInt16();} + template + inline atUint16 readVal(typename std::enable_if::value>::type* = 0) + {return readUint16();} /*! \brief Reads a Int32 and swaps to proper endianness depending on platform * and Stream settings, and advances the current position @@ -150,6 +163,9 @@ public: readUBytesToBuf(&val, 4); return m_endian == BigEndian ? utility::BigInt32(val) : utility::LittleInt32(val); } + template + inline atInt32 readVal(typename std::enable_if::value>::type* = 0) + {return readInt32();} /*! \brief Reads a Uint32 and swaps to proper endianness depending on platform * and Stream settings, and advances the current position @@ -161,6 +177,9 @@ public: */ inline atUint32 readUint32() {return readInt32();} + template + inline atUint32 readVal(typename std::enable_if::value>::type* = 0) + {return readUint32();} /*! \brief Reads a Int64 and swaps to proper endianness depending on platform * and Stream settings, and advances the current position @@ -176,6 +195,9 @@ public: readUBytesToBuf(&val, 8); return m_endian == BigEndian ? utility::BigInt64(val) : utility::LittleInt64(val); } + template + inline atInt64 readVal(typename std::enable_if::value>::type* = 0) + {return readInt64();} /*! \brief Reads a Uint64 and swaps to proper endianness depending on platform * and Stream settings, and advances the current position @@ -187,6 +209,9 @@ public: */ inline atUint64 readUint64() {return readInt64();} + template + inline atUint64 readVal(typename std::enable_if::value>::type* = 0) + {return readUint64();} /*! \brief Reads a float and swaps to proper endianness depending on platform * and Stream settings, and advances the current position @@ -202,6 +227,9 @@ public: readUBytesToBuf(&val, 4); return m_endian == BigEndian ? utility::BigFloat(val) : utility::LittleFloat(val); } + template + inline float readVal(typename std::enable_if::value>::type* = 0) + {return readFloat();} /*! \brief Reads a double and swaps to proper endianness depending on platform * and Stream settings, and advances the current position @@ -217,6 +245,9 @@ public: readUBytesToBuf(&val, 8); return m_endian == BigEndian ? utility::BigDouble(val) : utility::LittleDouble(val); } + template + inline double readVal(typename std::enable_if::value>::type* = 0) + {return readDouble();} /*! \brief Reads a bool and advances the current position * @@ -229,6 +260,9 @@ public: readUBytesToBuf(&val, 1); return val != 0; } + template + inline bool readVal(typename std::enable_if::value>::type* = 0) + {return readBool();} /*! \brief Reads an atVec2f (8 bytes) and advances the current position * @@ -251,6 +285,9 @@ public: } return val; } + template + inline atVec2f readVal(typename std::enable_if::value>::type* = 0) + {return readVec2f();} /*! \brief Reads an atVec3f (12 bytes) and advances the current position * @@ -275,6 +312,9 @@ public: } return val; } + template + inline atVec3f readVal(typename std::enable_if::value>::type* = 0) + {return readVec3f();} /*! \brief Reads an atVec4f (16 bytes) and advances the current position * @@ -301,6 +341,9 @@ public: } return val; } + template + inline atVec4f readVal(typename std::enable_if::value>::type* = 0) + {return readVec4f();} /*! \brief Reads a wide-char string, converts to UTF8 and advances the position in the file * @@ -360,6 +403,9 @@ public: return ret; } + template + inline std::string readVal(typename std::enable_if::value>::type* = 0) + {return readString();} /*! \brief Reads a wstring and advances the position in the file * @@ -388,6 +434,50 @@ public: return ret; } + template + inline std::wstring readVal(typename std::enable_if::value>::type* = 0) + {return readWString();} + + template + void enumerate(std::vector& vector, size_t count, + typename std::enable_if::value || + std::is_same::value || + std::is_same::value || + std::is_same::value>::type* = 0) + { + vector.clear(); + vector.reserve(count); + for (int i=0 ; i()); + } + + template + void enumerate(std::vector& vector, size_t count, + typename std::enable_if::value && + !std::is_same::value && + !std::is_same::value && + !std::is_same::value>::type* = 0) + { + vector.clear(); + vector.reserve(count); + for (int i=0 ; i + void enumerate(std::vector& vector, size_t count, std::function readf) + { + vector.clear(); + vector.reserve(count); + for (int i=0 ; i + void enumerate(const std::vector& vector, + typename std::enable_if::value || + std::is_same::value || + std::is_same::value || + std::is_same::value>::type* = 0) + { + for (const T& item : vector) + writeVal(item); + } + + template + void enumerate(const std::vector& vector, + typename std::enable_if::value && + !std::is_same::value && + !std::is_same::value && + !std::is_same::value>::type* = 0) + { + for (const T& item : vector) + item.write(*this); + } + protected: Endian m_endian; };