Skip to content

Commit ba6959d

Browse files
authored
Merge pull request #29 from ReflectCxx/release-2.0.dumpJson
refactored, type data dump as json.
2 parents 394105b + 8e531ab commit ba6959d

23 files changed

+260
-116
lines changed
Lines changed: 37 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11

2+
#include <filesystem>
3+
24
#include "MyReflection.h"
5+
#include "CxxMirrorToJson.h"
36

47
//User defined types to be reflected.
58
#include "Date.h"
@@ -8,9 +11,8 @@
811
#include "Complex.h"
912

1013
/*
11-
TestUtils provide the interface to test/compare reflected type objects with actual objects (retrived/created using
12-
strict Types) without exposing the actual type objects to "CxxReflectionTests" project.
13-
*/
14+
TestUtils, provides the interface to test/compare reflected type objects with actual objects (created via strict typing)
15+
without exposing the actual type objects to "CxxReflectionTests" project.*/
1416
#include "TestUtilsBook.h"
1517
#include "TestUtilsDate.h"
1618
#include "TestUtilsPerson.h"
@@ -26,76 +28,61 @@ CxxMirror& MyReflection::instance()
2628
{
2729
static CxxMirror cxxMirror = CxxMirror({
2830

29-
//Global function, not contained in any namespace.
30-
//No need to specify "function<>" template types, since its a unique function, no overloads.
31-
Reflect().function(str_getComplexNumAsString).build(getComplexNumAsString),
32-
33-
//Overloads, Specify the overload signature as template in "function<_signature...>"
34-
//if one of the function takes zero params, <void> must be used, else complie error.
35-
Reflect().function<void>(str_reverseString).build(reverseString),
36-
Reflect().function<string>(str_reverseString).build(reverseString),
37-
Reflect().function<const char*>(str_reverseString).build(reverseString),
31+
//global functions, not contained in any namespace.
32+
Reflect().function<void>(str_reverseString).build(reverseString), //function taking no arguments. '<void>' must be specified if other overload exists else not needed. compiler error otherwise.
33+
Reflect().function<string>(str_reverseString).build(reverseString), //overloaded function, takes 'string' arguments. '<string>' must be specified as template parameter.
34+
Reflect().function<const char*>(str_reverseString).build(reverseString), //overloaded function, takes 'const char*' arguments.
35+
Reflect().function(str_getComplexNumAsString).build(getComplexNumAsString), //unique function, no overloads, no need to specify signature as template parameters.
3836

39-
//Global functions, in "complex" namespace.
37+
//Grouping functions under a namespace, which is optional. they can be registered without it as well.
4038
Reflect().nameSpace(str_complex).function(str_setReal).build(complex::setReal),
4139
Reflect().nameSpace(str_complex).function(str_setImaginary).build(complex::setImaginary),
4240
Reflect().nameSpace(str_complex).function(str_getMagnitude).build(complex::getMagnitude),
4341

44-
//Date struct, in nsdate namespace. Ctors, Date()
45-
Reflect().nameSpace(date::ns).record<nsdate::Date>(date::struct_).constructor().build(),
46-
Reflect().nameSpace(date::ns).record<nsdate::Date>(date::struct_).constructor<string>().build(),
47-
Reflect().nameSpace(date::ns).record<nsdate::Date>(date::struct_).constructor<unsigned, unsigned, unsigned>().build(),
42+
//Constructors registration, class/struct name and type must be passed 'record<TYPE>("NAME")'.
43+
Reflect().nameSpace(date::ns).record<nsdate::Date>(date::struct_).constructor().build(), //default constructor. Destructor gets registered automatically if any constructor is registered.
44+
Reflect().nameSpace(date::ns).record<nsdate::Date>(date::struct_).constructor<string>().build(), //overloaded constructor, taking 'string' as argument, must be specified as template param.
45+
Reflect().nameSpace(date::ns).record<nsdate::Date>(date::struct_).constructor<unsigned, unsigned, unsigned>().build(), //again, the overloaded constructor.
46+
Reflect().nameSpace(date::ns).record<nsdate::Date>(date::struct_).constructor<nsdate::Date&>().build(), //Copy constructor, taking non-const ref as argument.
4847

49-
//Copy Ctor with non-const ref, Date()
50-
Reflect().nameSpace(date::ns).record<nsdate::Date>(date::struct_).constructor<nsdate::Date&>().build(),
51-
52-
//Calender, in nsdate namespace. Ctor only.
48+
//class Calender, default constructor. Instances will always be created on heap and managed using shared_ptr.
5349
Reflect().nameSpace(calender::ns).record<nsdate::Calender>(calender::struct_).constructor().build(),
50+
Reflect().record<Library>(library::class_).methodStatic(library::str_addBook).build(&Library::addBook), //Static method registration, 'methodStatic()' function must be used. compiler error otherwise.
5451

55-
//class 'Book', no namespace. constructor overloads.
52+
//class 'Book', methods & constructors.
5653
Reflect().record<Book>(book::class_).constructor().build(),
54+
Reflect().record<Book>(book::class_).constructor<const Book&>().build(), //copy constructor, taking const-ref.
5755
Reflect().record<Book>(book::class_).constructor<double, string>().build(),
58-
//copy constructor with const ref
59-
Reflect().record<Book>(book::class_).constructor<const Book&>().build(),
60-
61-
//Library class, no constructors.
62-
Reflect().record<Library>(library::class_).methodStatic(library::str_addBook).build(&Library::addBook),
63-
64-
//unique methods.
65-
Reflect().record<Book>(book::class_).method(book::str_setAuthor).build(&Book::setAuthor),
56+
Reflect().record<Book>(book::class_).method(book::str_setAuthor).build(&Book::setAuthor), //unique methods, no overloads.
6657
Reflect().record<Book>(book::class_).method(book::str_setDescription).build(&Book::setDescription),
6758
Reflect().record<Book>(book::class_).method(book::str_getPublishedOn).build(&Book::getPublishedOn),
68-
69-
//method overloads.
70-
Reflect().record<Book>(book::class_).method<void>(book::str_updateBookInfo).build(&Book::updateBookInfo),
71-
Reflect().record<Book>(book::class_).method<const char*, double, string>(book::str_updateBookInfo).build(&Book::updateBookInfo),
59+
Reflect().record<Book>(book::class_).method<void>(book::str_updateBookInfo).build(&Book::updateBookInfo), //method overloading, '<void>' must be specified since other overloads exists.
60+
Reflect().record<Book>(book::class_).method<const char*, double, string>(book::str_updateBookInfo).build(&Book::updateBookInfo),
7261
Reflect().record<Book>(book::class_).method<string, double, const char*>(book::str_updateBookInfo).build(&Book::updateBookInfo),
7362

74-
//Class 'Person', constructor.
63+
//class 'Person', methods & constructors.
7564
Reflect().record<Person>(person::class_).constructor().build(),
7665
Reflect().record<Person>(person::class_).constructor<string>().build(),
77-
78-
//Copy constructor overload based on const argument
79-
Reflect().record<Person>(person::class_).constructor<Person&>().build(),
80-
Reflect().record<Person>(person::class_).constructor<const Person&>().build(),
81-
82-
//const method. must use 'methodConst()'. Unique method, so no need to specify signature as template params.
83-
Reflect().record<Person>(person::class_).methodConst(person::str_updateLastName).build(&Person::updateLastName),
84-
85-
//const based method overloads. same signatures, but one is const, registered via 'methodConst()'.
66+
Reflect().record<Person>(person::class_).constructor<Person&>().build(), //copy constructor taking non-const ref argument.
67+
Reflect().record<Person>(person::class_).constructor<const Person&>().build(), //copy constructor taking const ref argument.
8668
Reflect().record<Person>(person::class_).method<void>(person::str_updateAddress).build(&Person::updateAddress),
87-
Reflect().record<Person>(person::class_).methodConst<void>(person::str_updateAddress).build(&Person::updateAddress),
8869
Reflect().record<Person>(person::class_).method<string>(person::str_updateAddress).build(&Person::updateAddress),
89-
Reflect().record<Person>(person::class_).methodConst<string>(person::str_updateAddress).build(&Person::updateAddress),
90-
91-
//Static method. unique.
70+
Reflect().record<Person>(person::class_).methodConst(person::str_updateLastName).build(&Person::updateLastName), //const method registration, 'methodConst()' function must be used. compiler error otherwise.
71+
Reflect().record<Person>(person::class_).methodConst<void>(person::str_updateAddress).build(&Person::updateAddress),
72+
Reflect().record<Person>(person::class_).methodConst<string>(person::str_updateAddress).build(&Person::updateAddress), //overloaded method based on 'const'.
9273
Reflect().record<Person>(person::class_).methodStatic(person::str_getDefaults).build(&Person::getDefaults),
93-
94-
//Static method overloads.
9574
Reflect().record<Person>(person::class_).methodStatic<void>(person::str_getProfile).build(&Person::getProfile),
9675
Reflect().record<Person>(person::class_).methodStatic<bool>(person::str_getProfile).build(&Person::getProfile),
9776
Reflect().record<Person>(person::class_).methodStatic<string, size_t>(person::str_getProfile).build(&Person::getProfile)
9877
});
9978

79+
80+
static bool dumped = false;
81+
if (!dumped) {
82+
const std::string pathStr = std::filesystem::current_path().string() + "/MyReflection.json";
83+
rtl::CxxMirrorToJson::dump(cxxMirror, pathStr);
84+
dumped = true;
85+
}
86+
10087
return cxxMirror;
10188
}

ReflectionTemplateLib/access/inc/CxxMirror.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,12 @@ namespace rtl {
1313
class Record;
1414
class Function;
1515

16-
class CxxMirror : detail::CxxReflection
16+
class CxxMirror : public detail::CxxReflection
1717
{
1818
public:
1919

2020
CxxMirror(const std::vector<Function>& pFunctions);
2121

22-
void dumpReflectionJson(const std::string& pFilePath);
23-
2422
std::optional<Record> getRecord(const std::string& pFunction);
2523

2624
std::optional<Function> getFunction(const std::string& pFunction);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#pragma once
2+
3+
namespace rtl {
4+
5+
namespace access {
6+
class CxxMirror;
7+
}
8+
9+
struct CxxMirrorToJson
10+
{
11+
static void dump(access::CxxMirror& pCxxMirror, const std::string& pFilePathStr);
12+
};
13+
}

ReflectionTemplateLib/access/inc/Function.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,11 @@ namespace rtl {
2626
const std::string m_function;
2727
const std::string m_namespace;
2828

29-
mutable std::string m_signatures;
3029
mutable std::vector<detail::FunctorId> m_functorIds;
3130

3231
Function();
3332
Function(const std::string& pNamespace, const std::string& pClassName, const std::string& pFuncName,
34-
const std::string& pSignature, const detail::FunctorId& pFunctorId,
35-
std::size_t pRecordTypeId, const TypeQ pQualifier);
33+
const detail::FunctorId& pFunctorId, std::size_t pRecordTypeId, const TypeQ pQualifier);
3634

3735
void addOverload(const Function& pOtherFunc) const;
3836

@@ -41,7 +39,7 @@ namespace rtl {
4139
protected:
4240

4341
Function(const Function& pOther, const detail::FunctorId& pFunctorId,
44-
const std::string& pFunctorName, const std::string& pSignatureStr);
42+
const std::string& pFunctorName);
4543

4644
const std::size_t hasSignatureId(const std::size_t& pSignatureId) const;
4745

@@ -51,8 +49,8 @@ namespace rtl {
5149
GETTER(std::string, RecordName, m_record)
5250
GETTER(std::string, Namespace, m_namespace)
5351
GETTER(std::string, FunctionName, m_function)
54-
GETTER(std::string, Signatures, m_signatures)
5552
GETTER(std::size_t, RecordTypeId, m_recordTypeId)
53+
GETTER(std::vector<detail::FunctorId>, Functors, m_functorIds)
5654

5755
const std::string getHashCode() const;
5856

ReflectionTemplateLib/access/inc/Method.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ namespace rtl {
4949
{
5050
Method(const Function& pFunction);
5151

52-
Method(const Function& pFunction, const detail::FunctorId& pFunctorId,
53-
const std::string& pFunctorName, const std::string& pSignatureStr);
52+
Method(const Function& pFunction, const detail::FunctorId& pFunctorId, const std::string& pFunctorName);
5453

5554
template<class ..._args>
5655
RStatus invokeCtor(_args...params) const;

ReflectionTemplateLib/access/inc/Record.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ namespace rtl {
1212
template<class ..._ctorArgs>
1313
inline const std::pair<RStatus, Instance> Record::instance(_ctorArgs ...params) const
1414
{
15-
const std::string& ctor = (m_recordName + Ctor::CTOR);
15+
const std::string& ctor = CtorName::ctor(m_recordName);
1616
const auto& itr = m_methods.find(ctor);
1717
if (itr != m_methods.end()) {
1818
const RStatus& status = itr->second.invokeCtor(params...);
1919
if (status) {
20-
const std::string& dctor = (m_recordName + Ctor::DCTOR);
20+
const std::string& dctor = CtorName::dctor(m_recordName);
2121
return std::make_pair(status, Instance(status.getReturn(), status, *getMethod(dctor)));
2222
}
2323
return std::make_pair(status, Instance());

ReflectionTemplateLib/access/src/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Create a variable containing the source files for your target
22
set(LOCAL_SOURCES
33
"${CMAKE_CURRENT_LIST_DIR}/CxxMirror.cpp"
4+
"${CMAKE_CURRENT_LIST_DIR}/CxxMirrorToJson.cpp"
45
"${CMAKE_CURRENT_LIST_DIR}/Function.cpp"
56
"${CMAKE_CURRENT_LIST_DIR}/Instance.cpp"
67
"${CMAKE_CURRENT_LIST_DIR}/Method.cpp"
@@ -15,6 +16,7 @@ SET(COMMON_HEADERS
1516

1617
SET(LOCAL_HEADERS
1718
"${PROJECT_SOURCE_DIR}/access/inc/CxxMirror.h"
19+
"${PROJECT_SOURCE_DIR}/access/inc/CxxMirrorToJson.h"
1820
"${PROJECT_SOURCE_DIR}/access/inc/Function.h"
1921
"${PROJECT_SOURCE_DIR}/access/inc/Function.hpp"
2022
"${PROJECT_SOURCE_DIR}/access/inc/Instance.h"
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
2+
#include <fstream>
3+
#include <filesystem>
4+
5+
#include "Method.h"
6+
#include "Record.h"
7+
#include "Function.h"
8+
#include "CxxMirror.h"
9+
#include "CxxMirrorToJson.h"
10+
11+
using namespace rtl::access;
12+
using namespace rtl::detail;
13+
14+
namespace
15+
{
16+
const std::string toJson(const FunctorId& pFunctorId)
17+
{
18+
std::stringstream sout;
19+
sout << "{\"hash_code\": \"" << std::to_string(pFunctorId.getHashCode()) << "\",";
20+
sout << "\"signature\": \"" << pFunctorId.getSignatureStr() << "\"}";
21+
return sout.str();
22+
}
23+
24+
const std::string toJson(const Function& pFunction)
25+
{
26+
std::stringstream sout;
27+
const auto& functors = pFunction.getFunctors();
28+
const std::string& record = pFunction.getRecordName();
29+
const std::string& nmspace = pFunction.getNamespace();
30+
31+
sout << "{" << (record.empty() ? "\"function\"" : "\"method\"") << ": \"" << pFunction.getFunctionName() << "\",";
32+
if (nmspace != rtl::NAMESPACE_GLOBAL) {
33+
sout << "\"namespace\": \"" << nmspace << "\",";
34+
}
35+
if (!record.empty()) {
36+
sout << "\"record\": \"" << record << "\",";
37+
}
38+
39+
int index = 0;
40+
sout << "\"functorId\": [";
41+
for (const auto& funtorId : functors) {
42+
sout << toJson(funtorId);
43+
if (++index < functors.size()) {
44+
sout << ", ";
45+
}
46+
}
47+
sout << "]}";
48+
return sout.str();
49+
}
50+
51+
52+
const std::string toJson(CxxMirror& pCxxMirror)
53+
{
54+
std::stringstream sout;
55+
sout << "[";
56+
bool atLeastOne = false;
57+
const auto& nsfuncMap = pCxxMirror.getNamespaceFunctionsMap();
58+
for (const auto& itr : nsfuncMap)
59+
{
60+
for (const auto& itr0 : itr.second)
61+
{
62+
const std::string& functionStr = toJson(itr0.second);
63+
sout << functionStr << ",";
64+
atLeastOne = true;
65+
}
66+
}
67+
68+
const auto& recfuncMap = pCxxMirror.getNamespaceRecordMap();
69+
for (const auto& itr : recfuncMap)
70+
{
71+
for (const auto& itr0 : itr.second)
72+
{
73+
for (const auto& itr1 : itr0.second.getMethodMap())
74+
{
75+
const std::string& methodStr = toJson(itr1.second);
76+
sout << methodStr << ",";
77+
atLeastOne = true;
78+
}
79+
}
80+
}
81+
82+
std::string str = sout.str();
83+
if (str.back() == ',') str.pop_back();
84+
str.push_back(']');
85+
return str;
86+
}
87+
}
88+
89+
90+
namespace rtl
91+
{
92+
void CxxMirrorToJson::dump(CxxMirror& pCxxMirror, const std::string& pFilePathStr)
93+
{
94+
std::string fileStr = pFilePathStr;
95+
std::replace(fileStr.begin(), fileStr.end(), '\\', '/');
96+
std::fstream fout(fileStr, std::ios::out);
97+
if (!fout.is_open()) {
98+
return;
99+
}
100+
fout << toJson(pCxxMirror);
101+
fout.flush();
102+
fout.close();
103+
if (fout.fail() || fout.bad()) {
104+
return;
105+
}
106+
}
107+
}

ReflectionTemplateLib/access/src/Function.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,33 +13,29 @@ namespace rtl {
1313
, m_recordTypeId(detail::TypeId<>::None)
1414
, m_record("")
1515
, m_function("")
16-
, m_signatures("")
1716
, m_namespace("")
1817
{
1918
}
2019

2120

2221
Function::Function(const std::string& pNamespace, const std::string& pRecord, const std::string& pFunction,
23-
const std::string& pSignature, const detail::FunctorId& pFunctorId,
24-
std::size_t pRecordTypeId, const TypeQ pQualifier)
22+
const detail::FunctorId& pFunctorId, std::size_t pRecordTypeId, const TypeQ pQualifier)
2523
: m_qualifier(pQualifier)
2624
, m_recordTypeId(pRecordTypeId)
2725
, m_functorIds({ pFunctorId })
2826
, m_record(pRecord)
2927
, m_function(pFunction)
30-
, m_signatures(pSignature)
3128
, m_namespace(pNamespace) {
3229
}
3330

3431

3532
Function::Function(const Function& pOther, const detail::FunctorId& pFunctorId,
36-
const std::string& pFunctorName, const std::string& pSignatureStr)
33+
const std::string& pFunctorName)
3734
: m_qualifier(pOther.m_qualifier)
3835
, m_recordTypeId(pOther.m_recordTypeId)
3936
, m_functorIds({ pFunctorId })
4037
, m_record(pOther.m_record)
4138
, m_function(pFunctorName)
42-
, m_signatures(pSignatureStr)
4339
, m_namespace(pOther.m_namespace) {
4440
}
4541

@@ -80,7 +76,6 @@ namespace rtl {
8076
}
8177

8278
m_functorIds.push_back(pOtherFunc.m_functorIds[0]);
83-
m_signatures.append("\n" + pOtherFunc.m_signatures);
8479
}
8580
}
8681
}

0 commit comments

Comments
 (0)