flatten 20260225
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.DS_Store
|
||||
*.pyc
|
||||
xcuserdata
|
||||
.bin
|
||||
650
Core_Variant.xcodeproj/project.pbxproj
Normal file
650
Core_Variant.xcodeproj/project.pbxproj
Normal file
@@ -0,0 +1,650 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 55;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
F608AAB128270AA8005C276B /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F608AAB028270AA8005C276B /* main.cpp */; };
|
||||
F608AAB528270AC8005C276B /* Variant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F608AA6C2826BCD8005C276B /* Variant.cpp */; };
|
||||
F608AAFC28271FF8005C276B /* VType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F608AA732826BCD8005C276B /* VType.cpp */; };
|
||||
F666630728679CB800239768 /* VType+IO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F666630628679CAE00239768 /* VType+IO.cpp */; };
|
||||
F666630828679CB900239768 /* VType+IO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F666630628679CAE00239768 /* VType+IO.cpp */; };
|
||||
F67119E02C8A63D300F72EE9 /* libCore_Variant.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F608A98C2826B791005C276B /* libCore_Variant.a */; };
|
||||
F67119E12C8A63D300F72EE9 /* libCore_Allocator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F61F9BEE2C6E4D7300F79137 /* libCore_Allocator.a */; };
|
||||
F67119E22C8A63D300F72EE9 /* libCore_Zero.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F608AAB928271CFE005C276B /* libCore_Zero.a */; };
|
||||
F69548BF28289357005D1B64 /* Variant+Functional.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F69548BE2828930D005D1B64 /* Variant+Functional.cpp */; };
|
||||
F6971F54282B123D008FBD17 /* Variant+Functional.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F69548BE2828930D005D1B64 /* Variant+Functional.cpp */; };
|
||||
F6971F55282B123D008FBD17 /* VType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F608AA732826BCD8005C276B /* VType.cpp */; };
|
||||
F69AB77F2B16D9DB000115BC /* VType_of.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F69AB77E2B16D8CE000115BC /* VType_of.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
F62C2BE12A500925007B43A3 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = F608A9842826B791005C276B /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = F608A98B2826B791005C276B;
|
||||
remoteInfo = Core_Variant;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
F608AAAC28270AA8005C276B /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /usr/share/man/man1/;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
F608A98C2826B791005C276B /* libCore_Variant.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCore_Variant.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F608AA6C2826BCD8005C276B /* Variant.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Variant.cpp; sourceTree = "<group>"; };
|
||||
F608AA6D2826BCD8005C276B /* Variant+Dispatch.inl */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Variant+Dispatch.inl"; sourceTree = "<group>"; };
|
||||
F608AA6E2826BCD8005C276B /* ConcreteVariant.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ConcreteVariant.hpp; sourceTree = "<group>"; };
|
||||
F608AA702826BCD8005C276B /* VType.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = VType.hpp; sourceTree = "<group>"; };
|
||||
F608AA712826BCD8005C276B /* VType+IO.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "VType+IO.h"; sourceTree = "<group>"; };
|
||||
F608AA722826BCD8005C276B /* ConcreteVariant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ConcreteVariant.h; sourceTree = "<group>"; };
|
||||
F608AA732826BCD8005C276B /* VType.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = VType.cpp; sourceTree = "<group>"; };
|
||||
F608AA742826BCD8005C276B /* VariantIO.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = VariantIO.hpp; sourceTree = "<group>"; };
|
||||
F608AA752826BCD8005C276B /* VariantIO.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VariantIO.h; sourceTree = "<group>"; };
|
||||
F608AA762826BCD8005C276B /* ConcreteVariant+IO.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ConcreteVariant+IO.h"; sourceTree = "<group>"; };
|
||||
F608AA772826BCD8005C276B /* VariantSerialization+IO.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = "VariantSerialization+IO.hpp"; sourceTree = "<group>"; };
|
||||
F608AA782826BCD8005C276B /* Variant+Dispatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Variant+Dispatch.h"; sourceTree = "<group>"; };
|
||||
F608AA792826BCD8005C276B /* VType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VType.h; sourceTree = "<group>"; };
|
||||
F608AA7A2826BCD8005C276B /* Variant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Variant.h; sourceTree = "<group>"; };
|
||||
F608AAAE28270AA8005C276B /* Core_Variant_Tests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Core_Variant_Tests; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F608AAB028270AA8005C276B /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
|
||||
F608AAB928271CFE005C276B /* libCore_Zero.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libCore_Zero.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F608AB6D2827F3CE005C276B /* Makefile.def */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.def; sourceTree = "<group>"; };
|
||||
F608AB6E2827F3CE005C276B /* Makefile.project */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.project; sourceTree = "<group>"; };
|
||||
F608AB9328282DF3005C276B /* Variant+VariantFunctionalUsingMap.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = "Variant+VariantFunctionalUsingMap.hpp"; sourceTree = "<group>"; };
|
||||
F608AB9428282E40005C276B /* Variant+VariantFunctionalUsingMapAndVectorCache.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = "Variant+VariantFunctionalUsingMapAndVectorCache.hpp"; sourceTree = "<group>"; };
|
||||
F608AB9528282E8E005C276B /* Variant+VariantFunctionalUsingSingleFunctionsObject.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = "Variant+VariantFunctionalUsingSingleFunctionsObject.hpp"; sourceTree = "<group>"; };
|
||||
F608AB9D28283866005C276B /* VariantSerialization.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VariantSerialization.h; sourceTree = "<group>"; };
|
||||
F608AB9E2828387E005C276B /* VariantSerialization.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = VariantSerialization.hpp; sourceTree = "<group>"; };
|
||||
F608ABA028283CC7005C276B /* Variant+IO.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = "Variant+IO.hpp"; sourceTree = "<group>"; };
|
||||
F608ABA128284A65005C276B /* VType+Functional.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = "VType+Functional.hpp"; sourceTree = "<group>"; };
|
||||
F608ABA228284B6C005C276B /* Variant+Functional.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = "Variant+Functional.hpp"; sourceTree = "<group>"; };
|
||||
F608ABA328285011005C276B /* Variant.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Variant.hpp; sourceTree = "<group>"; };
|
||||
F61F9BEC2C6E4CB400F79137 /* Makefile.project */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.project; sourceTree = "<group>"; };
|
||||
F61F9BEE2C6E4D7300F79137 /* libCore_Allocator.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libCore_Allocator.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F62C2BDE2A50043B007B43A3 /* Variant+VariantFunctionalUsingSingleFunctionsObjectPointer.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = "Variant+VariantFunctionalUsingSingleFunctionsObjectPointer.hpp"; sourceTree = "<group>"; };
|
||||
F62C2BDF2A5005A9007B43A3 /* Variant+Functional+Generate.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = "Variant+Functional+Generate.hpp"; sourceTree = "<group>"; };
|
||||
F666630628679CAE00239768 /* VType+IO.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = "VType+IO.cpp"; sourceTree = "<group>"; };
|
||||
F680BDB3285645BA00044A4F /* VType.inl */ = {isa = PBXFileReference; lastKnownFileType = text; path = VType.inl; sourceTree = "<group>"; };
|
||||
F680BDB628567BCF00044A4F /* VVector.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VVector.h; sourceTree = "<group>"; };
|
||||
F69548BE2828930D005D1B64 /* Variant+Functional.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = "Variant+Functional.cpp"; sourceTree = "<group>"; };
|
||||
F6971F5A282B123D008FBD17 /* libCore_Variant_iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCore_Variant_iOS.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F69AB77A2B16D210000115BC /* VType_of.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = VType_of.hpp; sourceTree = "<group>"; };
|
||||
F69AB77E2B16D8CE000115BC /* VType_of.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = VType_of.cpp; sourceTree = "<group>"; };
|
||||
F6BF9BE22E3901E3002E6AF0 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
|
||||
F6FC229E284F73DA00A6381D /* Notes.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Notes.txt; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
F608A98A2826B791005C276B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F608AAAB28270AA8005C276B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F67119E02C8A63D300F72EE9 /* libCore_Variant.a in Frameworks */,
|
||||
F67119E12C8A63D300F72EE9 /* libCore_Allocator.a in Frameworks */,
|
||||
F67119E22C8A63D300F72EE9 /* libCore_Zero.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F6971F56282B123D008FBD17 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
F608A9832826B791005C276B = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F608AAB828271CFE005C276B /* Frameworks */,
|
||||
F6BF9BE22E3901E3002E6AF0 /* Makefile */,
|
||||
F608AB6D2827F3CE005C276B /* Makefile.def */,
|
||||
F608AB6E2827F3CE005C276B /* Makefile.project */,
|
||||
F608A98D2826B791005C276B /* Products */,
|
||||
F608AAAF28270AA8005C276B /* tests */,
|
||||
F61D7C3F2E381655002A1AED /* tjp */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F608A98D2826B791005C276B /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F608A98C2826B791005C276B /* libCore_Variant.a */,
|
||||
F608AAAE28270AA8005C276B /* Core_Variant_Tests */,
|
||||
F6971F5A282B123D008FBD17 /* libCore_Variant_iOS.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F608A9B52826BA8C005C276B /* core */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F608AA6B2826BCD8005C276B /* variant */,
|
||||
);
|
||||
path = core;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F608AA6B2826BCD8005C276B /* variant */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F61F9BED2C6E4CEC00F79137 /* _tests */,
|
||||
F6FC229E284F73DA00A6381D /* Notes.txt */,
|
||||
F608AA722826BCD8005C276B /* ConcreteVariant.h */,
|
||||
F608AA6E2826BCD8005C276B /* ConcreteVariant.hpp */,
|
||||
F608AA762826BCD8005C276B /* ConcreteVariant+IO.h */,
|
||||
F608AA732826BCD8005C276B /* VType.cpp */,
|
||||
F680BDB3285645BA00044A4F /* VType.inl */,
|
||||
F608AA792826BCD8005C276B /* VType.h */,
|
||||
F608AA702826BCD8005C276B /* VType.hpp */,
|
||||
F69AB77A2B16D210000115BC /* VType_of.hpp */,
|
||||
F608ABA128284A65005C276B /* VType+Functional.hpp */,
|
||||
F608AA712826BCD8005C276B /* VType+IO.h */,
|
||||
F666630628679CAE00239768 /* VType+IO.cpp */,
|
||||
F680BDB628567BCF00044A4F /* VVector.h */,
|
||||
F608AA7A2826BCD8005C276B /* Variant.h */,
|
||||
F608ABA328285011005C276B /* Variant.hpp */,
|
||||
F608AA782826BCD8005C276B /* Variant+Dispatch.h */,
|
||||
F608AA6D2826BCD8005C276B /* Variant+Dispatch.inl */,
|
||||
F608ABA228284B6C005C276B /* Variant+Functional.hpp */,
|
||||
F62C2BDF2A5005A9007B43A3 /* Variant+Functional+Generate.hpp */,
|
||||
F69548BE2828930D005D1B64 /* Variant+Functional.cpp */,
|
||||
F608ABA028283CC7005C276B /* Variant+IO.hpp */,
|
||||
F608AB9328282DF3005C276B /* Variant+VariantFunctionalUsingMap.hpp */,
|
||||
F608AB9428282E40005C276B /* Variant+VariantFunctionalUsingMapAndVectorCache.hpp */,
|
||||
F608AB9528282E8E005C276B /* Variant+VariantFunctionalUsingSingleFunctionsObject.hpp */,
|
||||
F62C2BDE2A50043B007B43A3 /* Variant+VariantFunctionalUsingSingleFunctionsObjectPointer.hpp */,
|
||||
F608AA752826BCD8005C276B /* VariantIO.h */,
|
||||
F608AA742826BCD8005C276B /* VariantIO.hpp */,
|
||||
F608AB9D28283866005C276B /* VariantSerialization.h */,
|
||||
F608AB9E2828387E005C276B /* VariantSerialization.hpp */,
|
||||
F608AA772826BCD8005C276B /* VariantSerialization+IO.hpp */,
|
||||
);
|
||||
path = variant;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F608AAAF28270AA8005C276B /* tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F61F9BEC2C6E4CB400F79137 /* Makefile.project */,
|
||||
F608AAB028270AA8005C276B /* main.cpp */,
|
||||
);
|
||||
path = tests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F608AAB828271CFE005C276B /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F61F9BEE2C6E4D7300F79137 /* libCore_Allocator.a */,
|
||||
F608AAB928271CFE005C276B /* libCore_Zero.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F61D7C3F2E381655002A1AED /* tjp */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F608A9B52826BA8C005C276B /* core */,
|
||||
);
|
||||
path = tjp;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F61F9BED2C6E4CEC00F79137 /* _tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F608AA6C2826BCD8005C276B /* Variant.cpp */,
|
||||
F69AB77E2B16D8CE000115BC /* VType_of.cpp */,
|
||||
);
|
||||
path = _tests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
F608A9882826B791005C276B /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F6971F52282B123D008FBD17 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
F608A98B2826B791005C276B /* Core_Variant */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = F608A9902826B791005C276B /* Build configuration list for PBXNativeTarget "Core_Variant" */;
|
||||
buildPhases = (
|
||||
F608A9882826B791005C276B /* Headers */,
|
||||
F608A9892826B791005C276B /* Sources */,
|
||||
F608A98A2826B791005C276B /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Core_Variant;
|
||||
productName = Core_Variant;
|
||||
productReference = F608A98C2826B791005C276B /* libCore_Variant.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
F608AAAD28270AA8005C276B /* Core_Variant_Tests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = F608AAB228270AA8005C276B /* Build configuration list for PBXNativeTarget "Core_Variant_Tests" */;
|
||||
buildPhases = (
|
||||
F608AAAA28270AA8005C276B /* Sources */,
|
||||
F608AAAB28270AA8005C276B /* Frameworks */,
|
||||
F608AAAC28270AA8005C276B /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
F62C2BE22A500925007B43A3 /* PBXTargetDependency */,
|
||||
);
|
||||
name = Core_Variant_Tests;
|
||||
productName = Core_Variant_Tests;
|
||||
productReference = F608AAAE28270AA8005C276B /* Core_Variant_Tests */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
F6971F51282B123D008FBD17 /* Core_Variant_iOS */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = F6971F57282B123D008FBD17 /* Build configuration list for PBXNativeTarget "Core_Variant_iOS" */;
|
||||
buildPhases = (
|
||||
F6971F52282B123D008FBD17 /* Headers */,
|
||||
F6971F53282B123D008FBD17 /* Sources */,
|
||||
F6971F56282B123D008FBD17 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Core_Variant_iOS;
|
||||
productName = Core_Variant;
|
||||
productReference = F6971F5A282B123D008FBD17 /* libCore_Variant_iOS.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
F608A9842826B791005C276B /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
BuildIndependentTargetsInParallel = 1;
|
||||
DefaultBuildSystemTypeForWorkspace = Original;
|
||||
LastUpgradeCheck = 1330;
|
||||
TargetAttributes = {
|
||||
F608A98B2826B791005C276B = {
|
||||
CreatedOnToolsVersion = 13.3;
|
||||
};
|
||||
F608AAAD28270AA8005C276B = {
|
||||
CreatedOnToolsVersion = 13.3;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = F608A9872826B791005C276B /* Build configuration list for PBXProject "Core_Variant" */;
|
||||
compatibilityVersion = "Xcode 13.0";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = F608A9832826B791005C276B;
|
||||
productRefGroup = F608A98D2826B791005C276B /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
F608A98B2826B791005C276B /* Core_Variant */,
|
||||
F6971F51282B123D008FBD17 /* Core_Variant_iOS */,
|
||||
F608AAAD28270AA8005C276B /* Core_Variant_Tests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
F608A9892826B791005C276B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F666630828679CB900239768 /* VType+IO.cpp in Sources */,
|
||||
F69548BF28289357005D1B64 /* Variant+Functional.cpp in Sources */,
|
||||
F608AAFC28271FF8005C276B /* VType.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F608AAAA28270AA8005C276B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F69AB77F2B16D9DB000115BC /* VType_of.cpp in Sources */,
|
||||
F608AAB128270AA8005C276B /* main.cpp in Sources */,
|
||||
F608AAB528270AC8005C276B /* Variant.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F6971F53282B123D008FBD17 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F666630728679CB800239768 /* VType+IO.cpp in Sources */,
|
||||
F6971F54282B123D008FBD17 /* Variant+Functional.cpp in Sources */,
|
||||
F6971F55282B123D008FBD17 /* VType.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
F62C2BE22A500925007B43A3 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = F608A98B2826B791005C276B /* Core_Variant */;
|
||||
targetProxy = F62C2BE12A500925007B43A3 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
F608A98E2826B791005C276B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../Core_Zero,
|
||||
../Core_IO,
|
||||
../Core_Misc,
|
||||
../Core_Allocator,
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.6;
|
||||
LIBRARY_SEARCH_PATHS = "";
|
||||
"LIBRARY_SEARCH_PATHS[sdk=iphoneos*][arch=arm64]" = (
|
||||
"../Libraries/sdk/lib/Debug.iOS-arm64",
|
||||
"../Libraries/project/Debug.iOS-arm64",
|
||||
);
|
||||
"LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*]" = (
|
||||
"../Libraries/sdk/lib/Debug.iOS-sim",
|
||||
"../Libraries/project/Debug.iOS-sim",
|
||||
);
|
||||
"LIBRARY_SEARCH_PATHS[sdk=macosx*][arch=arm64]" = (
|
||||
"../Libraries/sdk/lib/Debug.Darwin-arm64",
|
||||
"../Libraries/project/Debug.Darwin-arm64",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
USE_HEADERMAP = NO;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
F608A98F2826B791005C276B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../Core_Zero,
|
||||
../Core_IO,
|
||||
../Core_Misc,
|
||||
../Core_Allocator,
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.6;
|
||||
LIBRARY_SEARCH_PATHS = "";
|
||||
"LIBRARY_SEARCH_PATHS[sdk=iphoneos*]" = (
|
||||
"../Libraries/sdk/lib/Release.iOS-arm64",
|
||||
"../Libraries/project/Release.iOS-arm64",
|
||||
);
|
||||
"LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*]" = (
|
||||
"../Libraries/sdk/lib/Release.iOS-sim",
|
||||
"../Libraries/project/Release.iOS-sim",
|
||||
);
|
||||
"LIBRARY_SEARCH_PATHS[sdk=macosx*][arch=arm64]" = (
|
||||
"../Libraries/sdk/lib/Release.Darwin-arm64",
|
||||
"../Libraries/project/Release.Darwin-arm64",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = macosx;
|
||||
USE_HEADERMAP = NO;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
F608A9912826B791005C276B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = T2M28D3T75;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
F608A9922826B791005C276B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = T2M28D3T75;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
F608AAB328270AA8005C276B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = T2M28D3T75;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
LOG_TEST,
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"${inherited}",
|
||||
../Core_Variant,
|
||||
);
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
F608AAB428270AA8005C276B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = T2M28D3T75;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = LOG_TEST;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"${inherited}",
|
||||
../Core_Variant,
|
||||
);
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
F6971F58282B123D008FBD17 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = T2M28D3T75;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
F6971F59282B123D008FBD17 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = T2M28D3T75;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
F608A9872826B791005C276B /* Build configuration list for PBXProject "Core_Variant" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
F608A98E2826B791005C276B /* Debug */,
|
||||
F608A98F2826B791005C276B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
F608A9902826B791005C276B /* Build configuration list for PBXNativeTarget "Core_Variant" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
F608A9912826B791005C276B /* Debug */,
|
||||
F608A9922826B791005C276B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
F608AAB228270AA8005C276B /* Build configuration list for PBXNativeTarget "Core_Variant_Tests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
F608AAB328270AA8005C276B /* Debug */,
|
||||
F608AAB428270AA8005C276B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
F6971F57282B123D008FBD17 /* Build configuration list for PBXNativeTarget "Core_Variant_iOS" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
F6971F58282B123D008FBD17 /* Debug */,
|
||||
F6971F59282B123D008FBD17 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = F608A9842826B791005C276B /* Project object */;
|
||||
}
|
||||
7
Core_Variant.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
Core_Variant.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1420"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "F608AAAD28270AA8005C276B"
|
||||
BuildableName = "Core_Variant_Tests"
|
||||
BlueprintName = "Core_Variant_Tests"
|
||||
ReferencedContainer = "container:Core_Variant.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES"
|
||||
viewDebuggingEnabled = "No">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "F608AAAD28270AA8005C276B"
|
||||
BuildableName = "Core_Variant_Tests"
|
||||
BlueprintName = "Core_Variant_Tests"
|
||||
ReferencedContainer = "container:Core_Variant.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<CommandLineArguments>
|
||||
<CommandLineArgument
|
||||
argument = ""Scenario: core::variant::VType_of""
|
||||
isEnabled = "NO">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = ""Scenario: core::variant::VType_of::other_namespace""
|
||||
isEnabled = "NO">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "-s -b"
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
</CommandLineArguments>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "F608AAAD28270AA8005C276B"
|
||||
BuildableName = "Core_Variant_Tests"
|
||||
BlueprintName = "Core_Variant_Tests"
|
||||
ReferencedContainer = "container:Core_Variant.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
2
Makefile
Normal file
2
Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
ROOTDIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))..)
|
||||
include $(ROOTDIR)/Core_Make/tjp/Make/Makefile
|
||||
6
Makefile.def
Executable file
6
Makefile.def
Executable file
@@ -0,0 +1,6 @@
|
||||
timprepscius.core.include := $(timprepscius.core.include) -I $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
timprepscius.core.link := $(timprepscius.core.link) -L $(dir $(realpath $(lastword $(MAKEFILE_LIST))))/.bin/$(OBJDIR)
|
||||
|
||||
timprepscius.core_variant.include := -I $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
timprepscius.core_variant.link := -L $(dir $(realpath $(lastword $(MAKEFILE_LIST))))/.bin/$(OBJDIR)
|
||||
|
||||
18
Makefile.project
Executable file
18
Makefile.project
Executable file
@@ -0,0 +1,18 @@
|
||||
include $(MAKEDIR)/Makefile.base
|
||||
|
||||
# use: ls -d core/*/ core/*/*/ | rev | cut -c 2- | rev | sed 's/$/ \\/'
|
||||
|
||||
PROJECTS := \
|
||||
tjp/core/variant \
|
||||
|
||||
#SRC_PCH := tjp/core/Precompile.pch
|
||||
|
||||
INCPATH := \
|
||||
$(timprepscius.libraries.cpp.include) \
|
||||
$(timprepscius.core.include)
|
||||
|
||||
LIBFILE := libCore_Variant.a
|
||||
|
||||
COPYTO := $(LIBRARIES_PROJECT)
|
||||
|
||||
include $(MAKEDIR)/Makefile.lib
|
||||
1
tests/Makefile
Symbolic link
1
tests/Makefile
Symbolic link
@@ -0,0 +1 @@
|
||||
../../Make/Makefile
|
||||
31
tests/Makefile.project
Executable file
31
tests/Makefile.project
Executable file
@@ -0,0 +1,31 @@
|
||||
include $(MAKEDIR)/Makefile.base
|
||||
|
||||
# use: ls -d core/*/ core/*/*/ | rev | cut -c 2- | rev | sed 's/$/ \\/'
|
||||
|
||||
PROJECTS := \
|
||||
. \
|
||||
../core/variant/_tests \
|
||||
|
||||
INCPATH := \
|
||||
$(timprepscius.libraries.cpp.include) \
|
||||
$(timprepscius.core.include)
|
||||
|
||||
LDPATH := $(timprepscius.libraries.cpp.link)
|
||||
|
||||
LIBS := \
|
||||
-lCore_Variant \
|
||||
-lCore_Zero \
|
||||
-lCore_Misc \
|
||||
-lCore_Allocator \
|
||||
-lz_
|
||||
|
||||
EXEFILE := Core_Variant_Tests.exe
|
||||
|
||||
#COPYTO := $(ROOTDIR)/.bin
|
||||
|
||||
ifeq (Darwin,$(SYS_NAME))
|
||||
LIBS += -lc++
|
||||
endif
|
||||
|
||||
|
||||
include $(MAKEDIR)/Makefile.bin
|
||||
20
tests/main.cpp
Normal file
20
tests/main.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
#define CATCH_CONFIG_RUNNER
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
|
||||
#include <tjp/core/log/Log.h>
|
||||
|
||||
using namespace tjp;
|
||||
using namespace core;
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
// xLogInitialize("Core_Variant_Tests.txt");
|
||||
xLogInitialize();
|
||||
xLogActivateStory("testing");
|
||||
xLogActivateStory("debug");
|
||||
|
||||
int result = Catch::Session().run( argc, argv );
|
||||
return result;
|
||||
}
|
||||
24
tjp/core/variant/ConcreteVariant+IO.h
Normal file
24
tjp/core/variant/ConcreteVariant+IO.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "ConcreteVariant.h"
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace variant {
|
||||
|
||||
template<typename IO, typename T>
|
||||
void io_bin(IO &io, ConcreteVariant<T> &v)
|
||||
{
|
||||
io.any((Variant &)v);
|
||||
}
|
||||
|
||||
template<typename IO, typename T>
|
||||
void io_json(IO &io, ConcreteVariant<T> &v)
|
||||
{
|
||||
io.any((Variant &)v);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
13
tjp/core/variant/ConcreteVariant.h
Normal file
13
tjp/core/variant/ConcreteVariant.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace variant {
|
||||
|
||||
template<typename T>
|
||||
struct ConcreteVariant;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
84
tjp/core/variant/ConcreteVariant.hpp
Normal file
84
tjp/core/variant/ConcreteVariant.hpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
|
||||
#include "ConcreteVariant.h"
|
||||
#include "Variant.h"
|
||||
#include <tjp/core/system/Debug.h>
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace variant {
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_CONCRETE_VARIANT
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
struct ConcreteVariant : Variant
|
||||
{
|
||||
typedef Variant Super;
|
||||
|
||||
#ifdef DEBUG_CONCRETE_VARIANT
|
||||
T *debug_ = nullptr;
|
||||
void execute_debug ()
|
||||
{
|
||||
debug_ = ptr_of(ptr());
|
||||
}
|
||||
#else
|
||||
void execute_debug () {}
|
||||
#endif
|
||||
|
||||
T *operator ->()
|
||||
{
|
||||
return &Super::template ref<T>();
|
||||
}
|
||||
|
||||
T &operator *()
|
||||
{
|
||||
return Super::template ref<T>();
|
||||
}
|
||||
|
||||
ConcreteVariant()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
ConcreteVariant(const U &rhs) :
|
||||
Super(rhs)
|
||||
{
|
||||
execute_debug();
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
ConcreteVariant &operator =(const U &rhs)
|
||||
{
|
||||
Super::template set<>(rhs);
|
||||
execute_debug();
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto ptr ()
|
||||
{
|
||||
return Super::template ptr<T>();
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
auto ptr ()
|
||||
{
|
||||
return Super::template ptr<U>();
|
||||
}
|
||||
|
||||
auto valid ()
|
||||
{
|
||||
return Super::template valid<T>();
|
||||
}
|
||||
|
||||
auto &variant ()
|
||||
{
|
||||
return (Super &)*this;
|
||||
}
|
||||
} ;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
21
tjp/core/variant/Notes.txt
Normal file
21
tjp/core/variant/Notes.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
When I redo VType
|
||||
|
||||
I want to make IOType to be 3 unsigned integers.
|
||||
type[0] is modifications, like, is it a vector
|
||||
type[1] is category, like 0 is intrinsics, 1 is core, 2, network, 3, crown, etc.
|
||||
type[2] is type, but with respect to category.
|
||||
|
||||
|
||||
VType is u64;
|
||||
|
||||
u32
|
||||
|
||||
struct {
|
||||
u8 nothing;
|
||||
u24 keyType;
|
||||
u24 valueType;
|
||||
u8 meta;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
115
tjp/core/variant/VType+Functional.hpp
Normal file
115
tjp/core/variant/VType+Functional.hpp
Normal file
@@ -0,0 +1,115 @@
|
||||
#pragma once
|
||||
|
||||
#include "VType.hpp"
|
||||
#include "VType_of.hpp"
|
||||
|
||||
#include <tjp/core/types/Types.h>
|
||||
#include <tjp/core/assert/debug_assert.h>
|
||||
|
||||
#include <tjp/core/ptr/Ptr.hpp>
|
||||
#include <tjp/core/type_traits/always_false.hpp>
|
||||
|
||||
//#include <tjp/core/type_traits/is_mappish.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <typeindex>
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
|
||||
inline
|
||||
bool operator <(const VType &lhs, const VType &rhs)
|
||||
{
|
||||
return lhs.id < rhs.id;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator ==(const VType &lhs, const VType &rhs)
|
||||
{
|
||||
return lhs.id == rhs.id;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator !=(const VType &lhs, const VType &rhs)
|
||||
{
|
||||
return lhs.id != rhs.id;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
VType vtype_of_custom(const StrongPtr<T> *)
|
||||
{
|
||||
return vtype_of<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct vtype_of_dispatch<StrongPtr<T>> {
|
||||
static
|
||||
constexpr
|
||||
auto dispatch(const StrongPtr<T> *t) {
|
||||
return vtype_of_custom(t);
|
||||
}
|
||||
} ;
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
VType VType::type_of()
|
||||
{
|
||||
return vtype_of<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
bool vtype_cast(const T &t, const VType &to)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
bool vtype_cast(const StrongPtr<T> &t, const VType &to)
|
||||
{
|
||||
return VType::type_cast<T>(to);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
bool vtype_cast_dispatch(const T *t, const VType &to)
|
||||
{
|
||||
return vtype_cast<T>(*t, to);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
bool vtype_cast_dispatch(const VType &to)
|
||||
{
|
||||
return vtype_cast_dispatch<T>(nullptr, to);
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr
|
||||
bool vtype_cast_dispatch<void>(const VType &to)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
bool vtype_cast(const VType &to)
|
||||
{
|
||||
return vtype_cast_dispatch<T>(to);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
bool VType::type_cast(const VType &to)
|
||||
{
|
||||
return vtype_cast_dispatch<T>(to);
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
13
tjp/core/variant/VType+IO.cpp
Normal file
13
tjp/core/variant/VType+IO.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "VType+IO.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
|
||||
std::ostream &operator <<(std::ostream &o, const VType &v)
|
||||
{
|
||||
return o << v.id;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
18
tjp/core/variant/VType+IO.h
Normal file
18
tjp/core/variant/VType+IO.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "VType.hpp"
|
||||
#include <iosfwd>
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
|
||||
template<typename IO>
|
||||
void io_(IO &io, VType &v)
|
||||
{
|
||||
io.any(v.id);
|
||||
}
|
||||
|
||||
std::ostream &operator <<(std::ostream &o, const VType &v);
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
10
tjp/core/variant/VType.cpp
Normal file
10
tjp/core/variant/VType.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "VType.hpp"
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
|
||||
const VType VType::Null = {0};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
48
tjp/core/variant/VType.h
Normal file
48
tjp/core/variant/VType.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <tjp/core/types/Types.h>
|
||||
#include <tjp/core/const_hash/Hash.hpp>
|
||||
#include <tjp/core/string/StringView.hpp>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
using VType_ID = u32;
|
||||
using VType_Namespace = u8;
|
||||
using VType_Class = u32;
|
||||
|
||||
constexpr
|
||||
VType_ID vtype_make(const VType_Namespace, const VType_Class);
|
||||
|
||||
constexpr
|
||||
VType_Namespace vtype_namespace(const VType_ID);
|
||||
|
||||
constexpr
|
||||
VType_Class vtype_class(const VType_ID);
|
||||
|
||||
struct VType;
|
||||
|
||||
bool operator <(const VType &lhs, const VType &rhs);
|
||||
bool operator ==(const VType &lhs, const VType &rhs);
|
||||
bool operator !=(const VType &lhs, const VType &rhs);
|
||||
|
||||
template<typename T>
|
||||
struct vtype_of_dispatch;
|
||||
|
||||
template<typename T>
|
||||
constexpr VType vtype_of(const T &);
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
VType vtype_of();
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
VType_ID vtype_id();
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
bool vtype_cast(const T &t, const VType &to);
|
||||
|
||||
using Type_ = VType;
|
||||
|
||||
} // namespace
|
||||
47
tjp/core/variant/VType.hpp
Normal file
47
tjp/core/variant/VType.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "VType.h"
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
|
||||
struct VType
|
||||
{
|
||||
using Namespace = VType_Namespace;
|
||||
using Class = VType_Class;
|
||||
using ID = VType_ID;
|
||||
|
||||
constexpr static Namespace primitive = 0;
|
||||
const static VType Null;
|
||||
|
||||
ID id;
|
||||
|
||||
static
|
||||
constexpr
|
||||
VType make(Namespace, Class);
|
||||
|
||||
template<typename T>
|
||||
static
|
||||
constexpr
|
||||
VType type_of();
|
||||
|
||||
template<typename T>
|
||||
static
|
||||
constexpr
|
||||
bool type_cast(const VType &to);
|
||||
|
||||
constexpr
|
||||
Namespace getNamespace() const {
|
||||
return vtype_namespace(id);
|
||||
}
|
||||
|
||||
constexpr
|
||||
Class getClass() const {
|
||||
return vtype_class(id);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
#include "VType.inl"
|
||||
39
tjp/core/variant/VType.inl
Normal file
39
tjp/core/variant/VType.inl
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <tjp/core/debug/Debug.h>
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
|
||||
constexpr VType_ID VType_Bits8 = 0xFF;
|
||||
|
||||
constexpr
|
||||
VType_ID vtype_make(const VType_Namespace n, const VType_Class c)
|
||||
{
|
||||
auto r =
|
||||
(VType_ID(c) << 8) |
|
||||
(VType_ID(n));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
constexpr
|
||||
VType_Namespace vtype_namespace(const VType_ID t)
|
||||
{
|
||||
return VType_Namespace(t & VType_Bits8);
|
||||
}
|
||||
|
||||
constexpr
|
||||
VType_Class vtype_class(const VType_ID t)
|
||||
{
|
||||
return VType_Class((t >> 8));
|
||||
}
|
||||
|
||||
inline
|
||||
constexpr
|
||||
VType VType::make(const Namespace n, const Class c)
|
||||
{
|
||||
return { .id = vtype_make(n, c) };
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
102
tjp/core/variant/VType_of.hpp
Normal file
102
tjp/core/variant/VType_of.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#pragma once
|
||||
|
||||
#include "VType.hpp"
|
||||
#include <tjp/core/rtti/TypeName.hpp>
|
||||
#include <tjp/core/const_hash/Hash.hpp>
|
||||
|
||||
#include <tjp/core/type_traits/always_false.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
constexpr
|
||||
auto vtype_id_class_using(const StringView &v)
|
||||
{
|
||||
return hash_compile<VType_ID>(v);
|
||||
}
|
||||
|
||||
constexpr
|
||||
auto vtype_id_using(const VType_Namespace n, const StringView &t)
|
||||
{
|
||||
return vtype_make(n, vtype_id_class_using(t));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
auto vtype_id_from(const VType_Namespace n, const T *t)
|
||||
{
|
||||
return vtype_id_using(n, type_name<T>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
VType vtype_from(const VType_Namespace n, const T *t)
|
||||
{
|
||||
return { vtype_id_from(n, t) };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
VType vtype_from(const T *t)
|
||||
{
|
||||
return vtype_from(0, t);
|
||||
}
|
||||
|
||||
static_assert(hash_compile<VType_ID>("tjp::core::variant::Variant") == 2549889722U);
|
||||
|
||||
// ------------
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
VType vtype_of_custom(const T *t)
|
||||
{
|
||||
return VType { vtype_id_from(0, t) };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct vtype_of_dispatch {
|
||||
static
|
||||
constexpr
|
||||
auto dispatch(const T *t) {
|
||||
return vtype_of_custom(t);
|
||||
}
|
||||
} ;
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
VType vtype_of()
|
||||
{
|
||||
// somehow, if these are not isolated as a constexpr before returning
|
||||
// the compiler does not discard the temporaries, and full type names
|
||||
// will exist in the code
|
||||
constexpr VType result =
|
||||
vtype_of_dispatch<T>::dispatch(static_cast<T *>(nullptr));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr
|
||||
VType vtype_of<void>()
|
||||
{
|
||||
// somehow, if these are not isolated as a constexpr before returning
|
||||
// the compiler does not discard the temporaries, and full type names
|
||||
// will exist in the code
|
||||
constexpr VType result =
|
||||
{ vtype_make(0, vtype_id_class_using("void")) };
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr
|
||||
VType_ID vtype_id()
|
||||
{
|
||||
constexpr auto result = vtype_of<T>().id;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
22
tjp/core/variant/VVector.h
Normal file
22
tjp/core/variant/VVector.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "VType.h"
|
||||
#include <tjp/core/containers/Vector.h>
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
|
||||
template<typename T>
|
||||
struct VVector : Vector<T>
|
||||
{
|
||||
using Super = Vector<T>;
|
||||
|
||||
VVector() {}
|
||||
VVector(size_t size) : Super(size) {}
|
||||
VVector(std::initializer_list<T> l) : Super(l) {}
|
||||
VVector(Super &&rhs) : Super(std::move(rhs)) {}
|
||||
VVector(const Super &rhs) : Super(rhs) {}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
28
tjp/core/variant/Variant+Dispatch.h
Normal file
28
tjp/core/variant/Variant+Dispatch.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "Variant+IO.hpp"
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace variant {
|
||||
|
||||
template<typename D>
|
||||
bool dispatch_type_builtin(int, D &d);
|
||||
|
||||
template<typename T, typename D, typename R>
|
||||
struct dispatch_variant;
|
||||
|
||||
template<typename T, typename D, typename R>
|
||||
struct dispatch_object;
|
||||
|
||||
template<typename T, typename D, typename R>
|
||||
struct dispatch_array;
|
||||
|
||||
template<typename T, typename D, typename R>
|
||||
struct dispatch_primitive;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
#include "Variant+Dispatch.inl"
|
||||
99
tjp/core/variant/Variant+Dispatch.inl
Normal file
99
tjp/core/variant/Variant+Dispatch.inl
Normal file
@@ -0,0 +1,99 @@
|
||||
#pragma once
|
||||
|
||||
#include "VType.hpp"
|
||||
#include "VariantSerialization.h"
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace variant {
|
||||
|
||||
template<typename D>
|
||||
bool dispatch_type_builtin_value(VType type, D &d)
|
||||
{
|
||||
switch(type.id) {
|
||||
|
||||
case vtype_id<bool>(): d.template visit<bool>(); return true;
|
||||
case vtype_id<u8>(): d.template visit<u8>(); return true;
|
||||
case vtype_id<s8>(): d.template visit<s8>(); return true;
|
||||
case vtype_id<u16>(): d.template visit<u16>(); return true;
|
||||
case vtype_id<s16>(): d.template visit<s16>(); return true;
|
||||
case vtype_id<u32>(): d.template visit<u32>(); return true;
|
||||
case vtype_id<s32>(): d.template visit<s32>(); return true;
|
||||
case vtype_id<u64>(): d.template visit<u64>(); return true;
|
||||
case vtype_id<s64>(): d.template visit<s64>(); return true;
|
||||
case vtype_id<r32>(): d.template visit<r32>(); return true;
|
||||
case vtype_id<r64>(): d.template visit<r64>(); return true;
|
||||
case vtype_id<std::string>(): d.template visit<std::string>(); return true;
|
||||
case vtype_id<VariantSerialization>(): d.template visit<VariantSerialization>(); return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename D, typename Type, typename T>
|
||||
void dispatch_primitive_if(D &d, const Type &type, T &t)
|
||||
{
|
||||
d.dispatch_primitive(type, t);
|
||||
}
|
||||
|
||||
template<typename T, typename D, typename R>
|
||||
struct dispatch_primitive
|
||||
{
|
||||
typedef dispatch_primitive<T,D,R> Self;
|
||||
T &variant;
|
||||
D &d;
|
||||
R r;
|
||||
|
||||
struct Value
|
||||
{
|
||||
Self &self;
|
||||
|
||||
template<typename V>
|
||||
void visit()
|
||||
{
|
||||
self.r.template visit<V>(self.variant);
|
||||
}
|
||||
} ;
|
||||
|
||||
dispatch_primitive(T &variant_, D &d_, R &&r_) :
|
||||
variant(variant_),
|
||||
d(d_),
|
||||
r(std::move(r_))
|
||||
{
|
||||
infer();
|
||||
}
|
||||
|
||||
void infer ()
|
||||
{
|
||||
Value v{*this};
|
||||
dispatch_primitive_if(d, variant.type, v);
|
||||
}
|
||||
} ;
|
||||
|
||||
template<typename T, typename D, typename R>
|
||||
struct dispatch_variant
|
||||
{
|
||||
typedef dispatch_variant<T,D,R> Self;
|
||||
T &variant;
|
||||
D &d;
|
||||
|
||||
dispatch_variant(T &variant_, D &d_, R &&r) :
|
||||
d(d_),
|
||||
variant(variant_)
|
||||
{
|
||||
infer(std::move(r));
|
||||
}
|
||||
|
||||
void infer (R &&r)
|
||||
{
|
||||
if (variant.type == T::Type::Null)
|
||||
r.visit_void(variant);
|
||||
else
|
||||
dispatch_primitive<T,D,R>(variant, d, std::move(r));
|
||||
}
|
||||
} ;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
27
tjp/core/variant/Variant+Functional+Generate.hpp
Normal file
27
tjp/core/variant/Variant+Functional+Generate.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
template<typename T>
|
||||
Functions generateVariantFunctions ();
|
||||
|
||||
template<typename T>
|
||||
Functions generateVariantFunctions ()
|
||||
{
|
||||
using Type = Type_;
|
||||
|
||||
return Functions {
|
||||
.construct = variant_construct<T>,
|
||||
.copy = variant_copy<T>,
|
||||
.destruct = variant_destruct<T>,
|
||||
.cast = Type::type_cast<T>
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Functions generateVariantFunctionsVoid ();
|
||||
|
||||
template<>
|
||||
inline
|
||||
Functions generateVariantFunctions<void> ()
|
||||
{
|
||||
return generateVariantFunctionsVoid();
|
||||
}
|
||||
|
||||
25
tjp/core/variant/Variant+Functional.cpp
Normal file
25
tjp/core/variant/Variant+Functional.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "Variant+Functional.hpp"
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace variant {
|
||||
|
||||
Variant::Type Variant::voidType = Variant::Type::template type_of<void>();
|
||||
|
||||
Functions generateVariantFunctionsVoid ()
|
||||
{
|
||||
using Type = Type_;
|
||||
|
||||
return Functions {
|
||||
[](Value &) {},
|
||||
[](Value &, const Value &) {},
|
||||
[](Value &) {},
|
||||
|
||||
[](const Type &) { return false; }
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
605
tjp/core/variant/Variant+Functional.hpp
Normal file
605
tjp/core/variant/Variant+Functional.hpp
Normal file
@@ -0,0 +1,605 @@
|
||||
#pragma once
|
||||
|
||||
#include "Variant.h"
|
||||
#include "VType.hpp"
|
||||
#include "VType+Functional.hpp"
|
||||
#include "VariantSerialization.h"
|
||||
|
||||
#include <tjp/core/types/Types.h>
|
||||
#include <tjp/core/debug/Debug.h>
|
||||
#include <tjp/core/assert/debug_assert.h>
|
||||
#include <tjp/core/exception/Exception.hpp>
|
||||
#include <tjp/core/ptr/Ptr.hpp>
|
||||
#include <tjp/core/allocator/SFINAE.hpp>
|
||||
#include <tjp/core/string/StringView.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace variant {
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_VARIANT
|
||||
#else
|
||||
// #define DEBUG_VARIANT
|
||||
#endif
|
||||
|
||||
// types
|
||||
struct Value_ {
|
||||
char memory [sizeof(core::ptr::StrongPtr<int>)];
|
||||
} __attribute__ ((aligned (8)));
|
||||
|
||||
typedef Value_ Value;
|
||||
|
||||
inline
|
||||
Value emptyValue () {
|
||||
Value v;
|
||||
memset(&v, 0, sizeof(v));
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename T> struct is_intrinsic : std::false_type {};
|
||||
template<> struct is_intrinsic<u8> : std::true_type {};
|
||||
template<> struct is_intrinsic<s8> : std::true_type {};
|
||||
template<> struct is_intrinsic<char> : std::true_type {};
|
||||
template<> struct is_intrinsic<u16> : std::true_type {};
|
||||
template<> struct is_intrinsic<s16> : std::true_type {};
|
||||
template<> struct is_intrinsic<u32> : std::true_type {};
|
||||
template<> struct is_intrinsic<s32> : std::true_type {};
|
||||
template<> struct is_intrinsic<u64> : std::true_type {};
|
||||
template<> struct is_intrinsic<s64> : std::true_type {};
|
||||
template<> struct is_intrinsic<r32> : std::true_type {};
|
||||
template<> struct is_intrinsic<r64> : std::true_type {};
|
||||
template<typename T> struct is_intrinsic<StrongPtr<T>> : std::true_type {};
|
||||
|
||||
template<typename T> struct is_variant : std::false_type {};
|
||||
template<> struct is_variant<Variant> : std::true_type {};
|
||||
|
||||
// ------ SFINAE
|
||||
|
||||
template<typename T>
|
||||
struct variant_type_ptr {
|
||||
|
||||
template<typename U, typename std::enable_if<is_intrinsic<U>::value, U>::type* = nullptr>
|
||||
static T *type_();
|
||||
|
||||
template<typename U, typename std::enable_if<!is_intrinsic<U>::value, U>::type* = nullptr>
|
||||
static StrongPtr<T> type_();
|
||||
|
||||
|
||||
typedef decltype(type_<T>()) type;
|
||||
} ;
|
||||
|
||||
|
||||
// ------ SFINAE
|
||||
|
||||
template<typename T>
|
||||
using has_variant_allocator = allocators::has_strong_allocator<T>;
|
||||
|
||||
// -----
|
||||
|
||||
// variant
|
||||
|
||||
template<typename T>
|
||||
T &deref (const Value &value) {
|
||||
static_assert(sizeof(T) <= sizeof(Value));
|
||||
auto *vp = &value;
|
||||
auto *pp = const_cast<T *>(reinterpret_cast<const T *>(vp));
|
||||
return *pp;
|
||||
} ;
|
||||
|
||||
struct Functions {
|
||||
using Type = Type_;
|
||||
|
||||
std::function<void(Value &)> construct;
|
||||
std::function<void(Value &, const Value &)> copy;
|
||||
std::function<void(Value &)> destruct;
|
||||
|
||||
std::function<bool(const Type &)> cast;
|
||||
};
|
||||
|
||||
DECLARE_EXCEPTION(CastException);
|
||||
|
||||
template<typename T>
|
||||
void variant_construct(Value &lhs) {
|
||||
new(&deref<T>(lhs)) T();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void variant_copy(Value &lhs, const Value &rhs) {
|
||||
deref<T>(lhs) = deref<T>(rhs);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void variant_destruct(Value &lhs) {
|
||||
deref<T>(lhs).~T();
|
||||
};
|
||||
|
||||
#include "Variant+Functional+Generate.hpp"
|
||||
|
||||
//#include "Variant+VariantFunctionalUsingSingleFunctionsObject.hpp"
|
||||
#include "Variant+VariantFunctionalUsingSingleFunctionsObjectPointer.hpp"
|
||||
|
||||
struct DefaultAllocator
|
||||
{
|
||||
template<typename T, typename ... Args>
|
||||
auto strong(Args && ...args)
|
||||
{
|
||||
return core::strong<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
} ;
|
||||
|
||||
#ifdef DEBUG_VARIANT
|
||||
#define CORE_VARIANT_INCLUDES_DEBUG_TYPE
|
||||
#endif
|
||||
|
||||
struct Variant
|
||||
{
|
||||
using Type = Type_;
|
||||
using Allocator_ = DefaultAllocator;
|
||||
using Functional = VariantFunctional;
|
||||
using Self = Variant;
|
||||
using value_type = Value;
|
||||
|
||||
Value value = emptyValue();
|
||||
mutable Functional functional;
|
||||
|
||||
static Type voidType;
|
||||
Type type = voidType;
|
||||
|
||||
[[no_unique_address]]
|
||||
Allocator_ defaultAllocator;
|
||||
|
||||
Variant()
|
||||
{
|
||||
auto &functions = functional.functionsFor(type);
|
||||
functions.construct(value);
|
||||
}
|
||||
|
||||
Variant(const Variant &rhs)
|
||||
{
|
||||
set(rhs);
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
Variant(const Variant &rhs, U &allocator)
|
||||
{
|
||||
set(rhs, allocator);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<!is_variant<T>::value, T>::type* = nullptr
|
||||
>
|
||||
Variant(const T &t)
|
||||
{
|
||||
auto &functions = functional.functionsFor(type);
|
||||
functions.construct(value);
|
||||
|
||||
set(t);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename U,
|
||||
typename std::enable_if<!is_variant<T>::value, T>::type* = nullptr
|
||||
>
|
||||
Variant(const T &t, U &allocator)
|
||||
{
|
||||
auto &functions = functional.functionsFor(type);
|
||||
functions.construct(value);
|
||||
|
||||
set(t, allocator);
|
||||
}
|
||||
|
||||
~Variant()
|
||||
{
|
||||
auto &functions = functional.functionsFor(type);
|
||||
functions.destruct(value);
|
||||
}
|
||||
|
||||
bool valid () const
|
||||
{
|
||||
return type != Type::template type_of<void>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool valid () const
|
||||
{
|
||||
return is_<T>() && (bool)ptr<T>();
|
||||
}
|
||||
|
||||
void clear ()
|
||||
{
|
||||
inferTypeName<void>();
|
||||
|
||||
if (type == voidType)
|
||||
return;
|
||||
|
||||
auto &f0 = functional.functionsFor(type);
|
||||
f0.destruct(value);
|
||||
|
||||
type = voidType;
|
||||
auto &f1 = functional.ensureFunctions<void>();
|
||||
f1.construct(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T &ensure_()
|
||||
{
|
||||
inferTypeName<T>();
|
||||
|
||||
if (!(type == Type::template type_of<void>()))
|
||||
{
|
||||
if (!is_<T>())
|
||||
{
|
||||
debug_assert(false);
|
||||
throw CastException{};
|
||||
}
|
||||
|
||||
return deref<T>(value);
|
||||
}
|
||||
|
||||
type = Type::template type_of<T>();
|
||||
auto &functions = functional.template ensureFunctions<T>();
|
||||
functions.construct(value);
|
||||
|
||||
return deref<T>(value);
|
||||
}
|
||||
|
||||
template<typename T, typename P>
|
||||
T &ensure_()
|
||||
{
|
||||
auto &r = ensure_<T>();
|
||||
inferTypeName<P>();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool is_() const
|
||||
{
|
||||
auto otherType = Type::template type_of<T>();
|
||||
|
||||
if (!(type == otherType))
|
||||
{
|
||||
auto &functions = functional.functionsFor(type);
|
||||
if (!functions.cast(otherType))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_serialization () const
|
||||
{
|
||||
return type == Type::template type_of<VariantSerialization>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T &ref_() const
|
||||
{
|
||||
if (!is_<T>())
|
||||
{
|
||||
throw CastException{};
|
||||
}
|
||||
|
||||
return deref<T>(value);
|
||||
}
|
||||
|
||||
#ifdef CORE_VARIANT_INCLUDES_DEBUG_TYPE
|
||||
// debug
|
||||
mutable StringView typeName;
|
||||
|
||||
template<typename T>
|
||||
void inferTypeName()
|
||||
{
|
||||
typeName = type_unique_label_stringview<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void copyTypeName(const T &rhs)
|
||||
{
|
||||
typeName = rhs.typeName;
|
||||
}
|
||||
|
||||
StringView getTypeName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
#else
|
||||
template<typename T>
|
||||
void inferTypeName () {}
|
||||
|
||||
template<typename T>
|
||||
void copyTypeName(const T &rhs) {}
|
||||
|
||||
StringView getTypeName() {
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
// copy
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<is_variant<T>::value, T>::type* = nullptr
|
||||
>
|
||||
void set(const T &rhs)
|
||||
{
|
||||
copyTypeName(rhs);
|
||||
|
||||
auto &functions = functional.functionsFor(type);
|
||||
functions.destruct(value);
|
||||
|
||||
type = rhs.type;
|
||||
auto &rhsFunctions = functional.ensureFunctions(type, rhs.functional.functionsFor(rhs.type));
|
||||
|
||||
rhsFunctions.construct(value);
|
||||
rhsFunctions.copy(value, rhs.value);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename U,
|
||||
typename std::enable_if<is_variant<T>::value, T>::type* = nullptr
|
||||
>
|
||||
void set(const T &rhs, U &)
|
||||
{
|
||||
set(rhs);
|
||||
}
|
||||
|
||||
// intrinsic
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
T *ptr()
|
||||
{
|
||||
if (!is_<T>())
|
||||
return nullptr;
|
||||
|
||||
return &ref<T>();
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
T *ptr() const
|
||||
{
|
||||
if (!is_<T>())
|
||||
return nullptr;
|
||||
|
||||
return &ref<T>();
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
void set(const T &rhs)
|
||||
{
|
||||
ensure_<T>() = rhs;
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename U,
|
||||
typename std::enable_if<is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
void set(const T &rhs, U &allocator)
|
||||
{
|
||||
ensure_<T>() = rhs;
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
T &ref()
|
||||
{
|
||||
return ref_<T>();
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
T &ref() const
|
||||
{
|
||||
return ref_<T>();
|
||||
}
|
||||
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename U,
|
||||
typename std::enable_if<is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
T &load(U &)
|
||||
{
|
||||
return ensure_<T>();
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
T &load()
|
||||
{
|
||||
return load<T>(defaultAllocator);
|
||||
}
|
||||
|
||||
|
||||
// pointer
|
||||
|
||||
template<typename TP, typename std::enable_if<std::is_pointer<TP>::value, TP>::type* = nullptr>
|
||||
void set(const TP rhs)
|
||||
{
|
||||
typedef typename std::remove_pointer<TP>::type T;
|
||||
typedef StrongPtr<T> P;
|
||||
|
||||
ensure_<P, T>() = rhs;
|
||||
}
|
||||
|
||||
|
||||
// complex
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<!is_variant<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!std::is_pointer<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
StrongPtr<T> ptr()
|
||||
{
|
||||
typedef StrongPtr<T> T_;
|
||||
if (!is_<T_>())
|
||||
return StrongPtr<T>();
|
||||
|
||||
return deref<T_>(value);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<!is_variant<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!std::is_pointer<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
const StrongPtr<T> ptr() const
|
||||
{
|
||||
typedef StrongPtr<T> T_;
|
||||
if (!is_<T_>())
|
||||
return StrongPtr<T>();
|
||||
|
||||
return deref<T_>(value);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename U,
|
||||
typename std::enable_if<!is_variant<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!std::is_pointer<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
void set(const T &rhs, U &allocator)
|
||||
{
|
||||
typedef StrongPtr<T> T_;
|
||||
auto &p = ensure_<T_, T>();
|
||||
if (!p)
|
||||
p = allocator.template strong<T>(rhs);
|
||||
else
|
||||
*p = rhs;
|
||||
}
|
||||
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<!is_variant<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!std::is_pointer<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
void set(const T &rhs)
|
||||
{
|
||||
set(rhs, defaultAllocator);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<!is_variant<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!std::is_pointer<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
T &ref()
|
||||
{
|
||||
typedef StrongPtr<T> T_;
|
||||
return *ref_<T_>();
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<!is_variant<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!std::is_pointer<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
T &ref() const
|
||||
{
|
||||
typedef StrongPtr<T> T_;
|
||||
return *ref_<T_>();
|
||||
}
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename U,
|
||||
typename std::enable_if<!std::is_void<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!is_variant<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!std::is_pointer<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
T &load(U &allocator)
|
||||
{
|
||||
typedef StrongPtr<T> T_;
|
||||
auto &ptr = ensure_<T_, T>();
|
||||
if (ptr == nullptr)
|
||||
ptr = allocator.template strong<T>();
|
||||
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<!std::is_void<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!is_variant<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!std::is_pointer<T>::value, T>::type* = nullptr,
|
||||
typename std::enable_if<!is_intrinsic<T>::value, T>::type* = nullptr
|
||||
>
|
||||
T &load()
|
||||
{
|
||||
return load<T>(defaultAllocator);
|
||||
}
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename U,
|
||||
typename std::enable_if<std::is_void<T>::value, T>::type* = nullptr
|
||||
>
|
||||
void load(U &allocator)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<std::is_void<T>::value, T>::type* = nullptr
|
||||
>
|
||||
void load()
|
||||
{
|
||||
return load<T>(defaultAllocator);
|
||||
}
|
||||
|
||||
// -- operator =
|
||||
|
||||
template<typename T>
|
||||
Variant &operator=(const T &rhs)
|
||||
{
|
||||
set(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// even though this should be covered by the operator = above,
|
||||
// somehow the compiler misses this occasionally and must be explicity specified
|
||||
Variant &operator=(const Variant &rhs)
|
||||
{
|
||||
set(rhs);
|
||||
return *this;
|
||||
}
|
||||
} ;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
137
tjp/core/variant/Variant+IO.hpp
Normal file
137
tjp/core/variant/Variant+IO.hpp
Normal file
@@ -0,0 +1,137 @@
|
||||
#pragma once
|
||||
|
||||
#include "VariantIO.hpp"
|
||||
#include "Variant.hpp"
|
||||
#include "VariantSerialization.hpp"
|
||||
#include "VariantSerialization+IO.hpp"
|
||||
|
||||
#include "VType.hpp"
|
||||
#include "VType+IO.h"
|
||||
#include <tjp/core/algorithm/remove_const_of_var.hpp>
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace variant {
|
||||
|
||||
template<typename IO, typename T>
|
||||
struct io_bin_variant {
|
||||
IO &io;
|
||||
|
||||
template<typename V>
|
||||
void visit(T &t)
|
||||
{
|
||||
auto &v = t.template as<V>(io);
|
||||
io.any(v);
|
||||
}
|
||||
|
||||
void visit_void(T &v) {}
|
||||
} ;
|
||||
|
||||
template<typename IO>
|
||||
void io_(IO &io, Variant &v)
|
||||
{
|
||||
VariantIO vio{ v.type, v };
|
||||
io.object("type", vio.type, "value", io.custom(vio));
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
#define IO_ENABLE_VARIANT_SERIALIZATION
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------
|
||||
#ifdef IO_ENABLE_VARIANT_SERIALIZATION
|
||||
|
||||
|
||||
// ----------------------
|
||||
|
||||
template<typename IO>
|
||||
void deserialize_(IO &io, Variant &variant, const StrongPtr<VariantSerialization> &serialization)
|
||||
{
|
||||
auto io_ = io.partial(serialization->block);
|
||||
variant = Variant();
|
||||
io_->any(variant);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
bool io_variant_deserialization_available(IO &io, Type_ type)
|
||||
{
|
||||
return io.variant_deserialization_available(type);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void deserialize_io(IO &io, Variant &variant)
|
||||
{
|
||||
using Type = Type_;
|
||||
if (variant.type == Type::template type_of<VariantSerialization>())
|
||||
{
|
||||
auto serialization = variant.template ptr<VariantSerialization>();
|
||||
if (io_variant_deserialization_available(io, serialization->type))
|
||||
{
|
||||
deserialize_(io, variant, serialization);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------
|
||||
|
||||
template<typename IO>
|
||||
void io_w_serialization(IO &io, const Variant &v)
|
||||
{
|
||||
VariantSerialization s(v, io);
|
||||
Variant v_(s);
|
||||
|
||||
VariantIO vio{ v_.type, v_ };
|
||||
io.object("type", vio.type, "value", io.custom(vio));
|
||||
}
|
||||
|
||||
template<typename IO, typename T>
|
||||
bool io_use_variant_serialization_for(IO &io, const T &t)
|
||||
{
|
||||
return io.use_variant_serialization_for(t);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void io_w(IO &io, const Variant &v)
|
||||
{
|
||||
typedef Variant V;
|
||||
if (io_use_variant_serialization_for(io, v))
|
||||
{
|
||||
return io_w_serialization(io, v);
|
||||
}
|
||||
|
||||
io_(io, const_cast<V&>(v));
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void io_r(IO &io, Variant &v)
|
||||
{
|
||||
VariantIO vio{ v.type, v };
|
||||
io.object("type", vio.type, "value", io.custom(vio));
|
||||
deserialize_io(io, v);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------
|
||||
#else
|
||||
// --------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
template<typename IO>
|
||||
void io_bin(IO &io, Variant &v) { return io_(io, v); }
|
||||
|
||||
template<typename IO>
|
||||
void io_json(IO &io, Variant &v) { return io_(io, v); }
|
||||
|
||||
|
||||
#endif
|
||||
// --------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
77
tjp/core/variant/Variant+VariantFunctionalUsingMap.hpp
Normal file
77
tjp/core/variant/Variant+VariantFunctionalUsingMap.hpp
Normal file
@@ -0,0 +1,77 @@
|
||||
|
||||
// VariantFunctionalUsingMap implements the functional aspect of a variant,
|
||||
// using both a Map to look up the functions object.
|
||||
//
|
||||
// I did this, because at the time of writing it was still unclear exactly what types would be needed
|
||||
// and when they would be needed, and then I also didn't know the overhead of constructing the
|
||||
// Function<> objects.
|
||||
|
||||
template<typename Type_>
|
||||
struct VariantFunctionalUsingMap
|
||||
{
|
||||
typedef Type_ Type;
|
||||
|
||||
struct FunctionsMap {
|
||||
SharedMutex mutex;
|
||||
std::map<Type, Functions<Type>> values;
|
||||
} ;
|
||||
|
||||
static FunctionsMap *functionsMap_;
|
||||
static std::once_flag initializeFunctionMapFlag;
|
||||
static void initializeFunctionMap ()
|
||||
{
|
||||
functionsMap_ = new FunctionsMap();
|
||||
(*functionsMap_).values[Type::template type_of<void>()] =
|
||||
generateVariantFunctionsVoid<Type>();
|
||||
}
|
||||
|
||||
static FunctionsMap &functionsMap ()
|
||||
{
|
||||
std::call_once(initializeFunctionMapFlag, initializeFunctionMap);
|
||||
return *functionsMap_;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static Functions<Type> &ensureFunctions()
|
||||
{
|
||||
Type type = Type::template type_of<T>();
|
||||
auto &functions = functionsMap();
|
||||
auto r = shared_lock_of(functions.mutex);
|
||||
|
||||
auto i = functions.values.find(type);
|
||||
if (i == functions.values.end())
|
||||
{
|
||||
r.unlock();
|
||||
auto w = lock_of(functions.mutex);
|
||||
|
||||
auto variantFunctions = generateVariantFunctions<Type, T>();
|
||||
auto emplaced = functions.values.insert({type, variantFunctions});
|
||||
i = emplaced.first;
|
||||
}
|
||||
|
||||
return i->second;
|
||||
}
|
||||
|
||||
static const Functions<Type> &ensureFunctions(Type type_, const Functions<Type> &functions_)
|
||||
{
|
||||
return functions_;
|
||||
}
|
||||
|
||||
static Functions<Type> &functionsFor(Type type)
|
||||
{
|
||||
auto &functions = functionsMap();
|
||||
auto r = shared_lock_of(functions.mutex);
|
||||
|
||||
auto i = functions.values.find(type);
|
||||
debug_assert(i != functions.values.end());
|
||||
|
||||
return i->second;
|
||||
}
|
||||
} ;
|
||||
|
||||
template<typename Type_>
|
||||
typename VariantFunctionalUsingMap<Type_>::FunctionsMap *VariantFunctionalUsingMap<Type_>::functionsMap_ = nullptr;
|
||||
|
||||
template<typename Type_>
|
||||
std::once_flag VariantFunctionalUsingMap<Type_>::initializeFunctionMapFlag;
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
|
||||
// VariantFunctionalUsingMapAndVectorCache implements the functional aspect of a variant,
|
||||
// using both a Map lookup for complex types and a Vector cache for indexing into commonly used
|
||||
// types. This is significantly faster.
|
||||
|
||||
template<typename Type_>
|
||||
struct VariantFunctionalUsingMapAndVectorCache
|
||||
{
|
||||
typedef Type_ Type;
|
||||
|
||||
struct CacheItem {
|
||||
bool cached = false;
|
||||
Functions<Type> functions;
|
||||
|
||||
void set(Functions<Type> &&functions_)
|
||||
{
|
||||
functions = std::move(functions_);
|
||||
cached = true;
|
||||
}
|
||||
} ;
|
||||
|
||||
struct FunctionsMap
|
||||
{
|
||||
typedef CacheItem Cache;
|
||||
static constexpr size_t maxCache = 256;
|
||||
Cache cache[maxCache];
|
||||
|
||||
SharedMutex mutex;
|
||||
std::map<Type, Functions<Type>> values;
|
||||
} ;
|
||||
|
||||
static FunctionsMap *functionsMap_;
|
||||
static std::once_flag initializeFunctionMapFlag;
|
||||
static void initializeFunctionMap ()
|
||||
{
|
||||
functionsMap_ = new FunctionsMap();
|
||||
|
||||
auto type = Type::template type_of<void>();
|
||||
|
||||
auto cacheIndex = type.id;
|
||||
debug_assert(cacheIndex < functionsMap_->maxCache);
|
||||
|
||||
auto &item = functionsMap_->cache[cacheIndex];
|
||||
item.set(generateVariantFunctionsVoid<Type>());
|
||||
}
|
||||
|
||||
static FunctionsMap &functionsMap ()
|
||||
{
|
||||
std::call_once(initializeFunctionMapFlag, initializeFunctionMap);
|
||||
return *functionsMap_;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static Functions<Type> &ensureFunctions()
|
||||
{
|
||||
auto &functions = functionsMap();
|
||||
|
||||
Type type = Type::template type_of<T>();
|
||||
|
||||
auto cacheIndex = type.id;
|
||||
if (cacheIndex < functions.maxCache)
|
||||
{
|
||||
auto &item = functions.cache[cacheIndex];
|
||||
if (item.cached)
|
||||
return item.functions;
|
||||
|
||||
auto w = lock_of(functions.mutex);
|
||||
if (!item.cached)
|
||||
item.set(generateVariantFunctions<Type, T>());
|
||||
|
||||
return item.functions;
|
||||
}
|
||||
|
||||
auto r = shared_lock_of(functions.mutex);
|
||||
|
||||
auto i = functions.values.find(type);
|
||||
if (i == functions.values.end())
|
||||
{
|
||||
r.unlock();
|
||||
auto w = lock_of(functions.mutex);
|
||||
|
||||
auto variantFunctions = generateVariantFunctions<Type, T>();
|
||||
auto emplaced = functions.values.insert({type, variantFunctions});
|
||||
i = emplaced.first;
|
||||
}
|
||||
|
||||
return i->second;
|
||||
}
|
||||
|
||||
static const Functions<Type> &ensureFunctions(Type type_, const Functions<Type> &functions_)
|
||||
{
|
||||
return functions_;
|
||||
}
|
||||
|
||||
static Functions<Type> &functionsFor(Type type)
|
||||
{
|
||||
auto &functions = functionsMap();
|
||||
|
||||
auto cacheIndex = type.id;
|
||||
if (cacheIndex < functions.maxCache)
|
||||
{
|
||||
auto &item = functions.cache[cacheIndex];
|
||||
debug_assert(item.cached);
|
||||
|
||||
return item.functions;
|
||||
}
|
||||
|
||||
auto r = shared_lock_of(functions.mutex);
|
||||
|
||||
auto i = functions.values.find(type);
|
||||
debug_assert(i != functions.values.end());
|
||||
|
||||
return i->second;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
template<typename Type_>
|
||||
typename VariantFunctionalUsingMapAndVectorCache<Type_>::FunctionsMap *VariantFunctionalUsingMapAndVectorCache<Type_>::functionsMap_ = nullptr;
|
||||
|
||||
template<typename Type_>
|
||||
std::once_flag VariantFunctionalUsingMapAndVectorCache<Type_>::initializeFunctionMapFlag;
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
|
||||
// VariantFunctionalUsingSingleFunctionsObject implements the functional aspect of a variant
|
||||
// without using any lookups or caching. If the Function<> objects don't use the heap, and
|
||||
// are nearly instantaneous to construct, this is the best option.
|
||||
//
|
||||
// And it turns out that Function<> objects don't use the heap if they capture < threshold bytes
|
||||
// and are in fact nearly instantaneous to construct
|
||||
|
||||
struct VariantFunctionalUsingSingleFunctionsObject
|
||||
{
|
||||
typedef Type_ Type;
|
||||
|
||||
Type type = Type::template type_of<void>();
|
||||
Functions functions = generateVariantFunctions<void>();
|
||||
|
||||
template<typename T>
|
||||
const Functions &ensureFunctions()
|
||||
{
|
||||
type = Type::template type_of<T>();
|
||||
functions = generateVariantFunctions<T>();
|
||||
return functions;
|
||||
}
|
||||
|
||||
const Functions &ensureFunctions(Type type_, const Functions &functions_)
|
||||
{
|
||||
type = type_;
|
||||
functions = functions_;
|
||||
return functions;
|
||||
}
|
||||
|
||||
const Functions &functionsFor(Type type) const
|
||||
{
|
||||
debug_assert(type == type);
|
||||
return functions;
|
||||
}
|
||||
} ;
|
||||
|
||||
using VariantFunctional = VariantFunctionalUsingSingleFunctionsObject;
|
||||
@@ -0,0 +1,67 @@
|
||||
|
||||
|
||||
// VariantFunctionalUsingSingleFunctionsObject implements the functional aspect of a variant
|
||||
// without using any lookups or caching. If the Function<> objects don't use the heap, and
|
||||
// are nearly instantaneous to construct, this is the best option.
|
||||
//
|
||||
// And it turns out that Function<> objects don't use the heap if they capture < threshold bytes
|
||||
// and are in fact nearly instantaneous to construct
|
||||
|
||||
template<typename T>
|
||||
struct SingleFunctionsObject {
|
||||
static const Functions functions_;
|
||||
|
||||
static const Functions *functions() {
|
||||
return &functions_;
|
||||
}
|
||||
} ;
|
||||
|
||||
template<typename T>
|
||||
const Functions SingleFunctionsObject<T>::functions_ = generateVariantFunctions<T>();
|
||||
|
||||
#ifdef DEBUG_VARIANT
|
||||
#define VARIANT_FUNCTIONS_INCLUDE_TYPE
|
||||
#endif
|
||||
|
||||
struct VariantFunctionalUsingSingleFunctionsObjectPointer
|
||||
{
|
||||
typedef Type_ Type;
|
||||
|
||||
#ifdef VARIANT_FUNCTIONS_INCLUDE_TYPE
|
||||
Type type = Type::template type_of<void>();
|
||||
#endif
|
||||
|
||||
const Functions *functions = SingleFunctionsObject<void>::functions();
|
||||
|
||||
void setType(Type type_)
|
||||
{
|
||||
#ifdef VARIANT_FUNCTIONS_INCLUDE_TYPE
|
||||
type = type_;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const Functions &ensureFunctions()
|
||||
{
|
||||
setType(Type::template type_of<T>());
|
||||
functions = SingleFunctionsObject<T>::functions();
|
||||
return *functions;
|
||||
}
|
||||
|
||||
const Functions &ensureFunctions(Type type_, const Functions &functions_)
|
||||
{
|
||||
setType(type_);
|
||||
functions = &functions_;
|
||||
return *functions;
|
||||
}
|
||||
|
||||
const Functions &functionsFor(Type type) const
|
||||
{
|
||||
#ifdef VARIANT_FUNCTIONS_INCLUDE_TYPE
|
||||
debug_assert(type == type);
|
||||
#endif
|
||||
return *functions;
|
||||
}
|
||||
} ;
|
||||
|
||||
using VariantFunctional = VariantFunctionalUsingSingleFunctionsObjectPointer;
|
||||
23
tjp/core/variant/Variant.h
Normal file
23
tjp/core/variant/Variant.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "VType.h"
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace variant {
|
||||
|
||||
struct DefaultAllocator;
|
||||
|
||||
struct Variant;
|
||||
struct VariantSerialization;
|
||||
struct Functions;
|
||||
|
||||
struct CastException;
|
||||
|
||||
template<typename T>
|
||||
Functions generateVariantFunctions ();
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
12
tjp/core/variant/Variant.hpp
Normal file
12
tjp/core/variant/Variant.hpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Variant+Functional.hpp"
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace variant {
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
13
tjp/core/variant/VariantIO.h
Normal file
13
tjp/core/variant/VariantIO.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Variant.h"
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace variant {
|
||||
|
||||
struct VariantIO;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
41
tjp/core/variant/VariantIO.hpp
Normal file
41
tjp/core/variant/VariantIO.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "VariantIO.h"
|
||||
#include "Variant.hpp"
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace variant {
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
struct VariantIO {
|
||||
typedef Type_ Type;
|
||||
|
||||
Type type;
|
||||
Variant &variant;
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename IO,
|
||||
typename std::enable_if<has_variant_allocator<IO>::value, IO>::type* = nullptr
|
||||
>
|
||||
auto &as(IO &io)
|
||||
{
|
||||
return variant.load<T>(io.allocator);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename IO,
|
||||
typename std::enable_if<!has_variant_allocator<IO>::value, IO>::type* = nullptr
|
||||
>
|
||||
auto &as(IO &io)
|
||||
{
|
||||
return variant.load<T>();
|
||||
}
|
||||
} ;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
24
tjp/core/variant/VariantSerialization+IO.hpp
Normal file
24
tjp/core/variant/VariantSerialization+IO.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace variant {
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
template<typename IO>
|
||||
void io_(IO &io, VariantSerialization &v)
|
||||
{
|
||||
io.object("type", v.type, "block", v.block);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void io_json(IO &io, VariantSerialization &v) { return io_(io, v); }
|
||||
|
||||
template<typename IO>
|
||||
void io_bin(IO &io, VariantSerialization &v) { return io_(io, v); }
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
14
tjp/core/variant/VariantSerialization.h
Normal file
14
tjp/core/variant/VariantSerialization.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "VType.hpp"
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace variant {
|
||||
|
||||
struct VariantSerialization;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
36
tjp/core/variant/VariantSerialization.hpp
Normal file
36
tjp/core/variant/VariantSerialization.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "VariantIO.hpp"
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace variant {
|
||||
|
||||
struct VariantSerialization
|
||||
{
|
||||
typedef std::vector<char> Block;
|
||||
|
||||
Type_ type;
|
||||
Block block;
|
||||
|
||||
VariantSerialization() {}
|
||||
|
||||
template<typename IO>
|
||||
VariantSerialization(const Variant &v, IO &io)
|
||||
{
|
||||
auto &v_ = const_cast<Variant &>(v);
|
||||
|
||||
auto io_ = io.partial();
|
||||
|
||||
VariantIO vio{ v_.type, v_ };
|
||||
io_.object("type", v.type, "value", io_.custom(vio));
|
||||
|
||||
type = v.type;
|
||||
block = io_.partial_serialization();
|
||||
} ;
|
||||
} ;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
132
tjp/core/variant/_tests/VType_of.cpp
Normal file
132
tjp/core/variant/_tests/VType_of.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
#include <tjp/core/variant/VType.hpp>
|
||||
#include <tjp/core/variant/VType_of.hpp>
|
||||
#include <tjp/core/variant/VType+IO.h>
|
||||
#include <tjp/core/variant/VType+Functional.hpp>
|
||||
|
||||
#include <tjp/core/log/Log.h>
|
||||
#include <tjp/core/log/LogOf.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
|
||||
namespace tjp::core {
|
||||
namespace variant_testing {
|
||||
|
||||
struct X1 {};
|
||||
|
||||
constexpr
|
||||
VType vtype_of_custom(const X1 *)
|
||||
{
|
||||
return vtype_from("X");
|
||||
}
|
||||
|
||||
SCENARIO("core::variant::VType_of_strings")
|
||||
{
|
||||
GIVEN("compile vs runtime")
|
||||
{
|
||||
struct abcdefgh {};
|
||||
|
||||
// sLogTest("testing",
|
||||
// logVar(type_name<abcdefgh>()));
|
||||
|
||||
constexpr auto x = vtype_of<abcdefgh>();
|
||||
|
||||
sLogTest("testing",
|
||||
logVar(x));
|
||||
|
||||
sLogTest("testing",
|
||||
logVar(vtype_of<abcdefgh>()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO("core::variant::VType_of")
|
||||
{
|
||||
GIVEN("compile vs runtime")
|
||||
{
|
||||
using A = VType;
|
||||
|
||||
sLogTest("testing",
|
||||
logVar(type_name<VType>()) <<
|
||||
logVar(type_name<A>()) <<
|
||||
logVar(type_name<VType_ID>()) <<
|
||||
logVar(type_name<std::iostream>()) <<
|
||||
logVar(type_name<std::numeric_limits<int>>())
|
||||
);
|
||||
|
||||
sLogTest("testing",
|
||||
logVar(rtti::impl::format.leading_junk) <<
|
||||
logVar(rtti::impl::format.trailing_junk)
|
||||
);
|
||||
|
||||
sLogTest("testing",
|
||||
"\n" << rtti::impl::RawTypeName<int>() <<
|
||||
"\n" << type_name<int>() <<
|
||||
|
||||
"\n" << rtti::impl::RawTypeName<VType>() <<
|
||||
"\n" << type_name<VType>() <<
|
||||
|
||||
"\n" << rtti::impl::RawTypeName<A>() <<
|
||||
"\n" << type_name<A>() <<
|
||||
|
||||
"\n" << rtti::impl::RawTypeName<VType_ID>() <<
|
||||
"\n" << type_name<VType_ID>() <<
|
||||
|
||||
"\n" << rtti::impl::RawTypeName<std::iostream>() <<
|
||||
"\n" << type_name<std::iostream>() <<
|
||||
|
||||
"\n" << rtti::impl::RawTypeName<std::numeric_limits<int>>() <<
|
||||
"\n" << type_name<std::numeric_limits<int>>()
|
||||
);
|
||||
|
||||
sLogTest("testing",
|
||||
logVar(hash_compile<u64>(type_name<VType>())) <<
|
||||
logVar(hash_compile<u64>(type_name<VType_ID>())) <<
|
||||
logVar(hash_runtime<u64>(type_name<VType>())) <<
|
||||
logVar(hash_runtime<u64>(type_name<VType_ID>()))
|
||||
);
|
||||
|
||||
constexpr VType v0 = vtype_of<VType>();
|
||||
constexpr VType v1 = vtype_of<VType_ID>();
|
||||
|
||||
constexpr VType xt = vtype_of<X1>();
|
||||
constexpr VType xt_ = core::vtype_from("X");
|
||||
constexpr int xti = xt.id;
|
||||
constexpr int xt_i = xt_.id;
|
||||
|
||||
static_assert(xti == xt_i);
|
||||
REQUIRE(xt.id == xt_.id);
|
||||
|
||||
constexpr VType xtv = VType::type_of<X1>();
|
||||
REQUIRE(xt == xtv);
|
||||
|
||||
|
||||
|
||||
|
||||
sLogTest("testing",
|
||||
logVar(v0) << logVar(v1));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace variant_testing_2 {
|
||||
|
||||
SCENARIO("core::variant::VType_of::other_namespace")
|
||||
{
|
||||
GIVEN("compile vs runtime")
|
||||
{
|
||||
constexpr VType xt = vtype_of<variant_testing::X1>();
|
||||
constexpr VType xt_ = vtype_from("X");
|
||||
REQUIRE(xt == xt_);
|
||||
|
||||
constexpr VType xtv = VType::type_of<variant_testing::X1>();
|
||||
REQUIRE(xt == xtv);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
379
tjp/core/variant/_tests/Variant.cpp
Normal file
379
tjp/core/variant/_tests/Variant.cpp
Normal file
@@ -0,0 +1,379 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
#include <tjp/core/string/String.h>
|
||||
#include <tjp/core/variant/Variant.hpp>
|
||||
#include <tjp/core/variant/Variant+IO.hpp>
|
||||
#include <tjp/core/variant/VType+IO.h>
|
||||
#include <tjp/core/variant/Variant+Dispatch.h>
|
||||
#include <tjp/core/io/bin/IO.h>
|
||||
#include <tjp/core/ptr/Ptr+IO.h>
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
#include <tjp/core/algorithm/unused.hpp>
|
||||
|
||||
#include <tjp/core/log/Log.h>
|
||||
#include <tjp/core/log/LogOf.h>
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
// because the custom map type is actually in the std namespace
|
||||
// we can either make it in the std namespace or put it in the variant namespace
|
||||
namespace tjp::core::variant {
|
||||
|
||||
typedef std::map<std::string,Variant> CustomMapType;
|
||||
|
||||
constexpr
|
||||
VType vtype_of_custom(const CustomMapType *) { return VType::make(30, 13); }
|
||||
|
||||
} // namespace
|
||||
// -------------------------------------------------------------------------------
|
||||
|
||||
namespace tjp::core::variant::test_compile {
|
||||
|
||||
typedef std::map<std::string,Variant> CustomMapType;
|
||||
|
||||
constexpr
|
||||
VType vtype_of_custom(const CustomMapType *) { return VType::make(30, 13); }
|
||||
|
||||
struct Custom
|
||||
{
|
||||
int i;
|
||||
} ;
|
||||
|
||||
constexpr
|
||||
VType vtype_of_custom(const Custom *) { return VType::make(64, 23); }
|
||||
|
||||
struct External
|
||||
{
|
||||
int x;
|
||||
} ;
|
||||
|
||||
constexpr
|
||||
VType vtype_of_custom(const External *) { return VType::make(65, 33); }
|
||||
|
||||
template<typename IO>
|
||||
void io_bin(IO &io, Custom &a)
|
||||
{
|
||||
io.all(a.i);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void io_bin(IO &io, External &a)
|
||||
{
|
||||
io.all(a.x);
|
||||
}
|
||||
|
||||
struct DispatchVariant
|
||||
{
|
||||
template<typename IO>
|
||||
void dispatch_custom(IO &io, VariantIO &v)
|
||||
{
|
||||
core::variant::dispatch_variant(
|
||||
v,
|
||||
*this,
|
||||
io_bin_variant<IO, VariantIO> { io }
|
||||
);
|
||||
}
|
||||
|
||||
template<typename D>
|
||||
void dispatch_primitive(VType type, D &d)
|
||||
{
|
||||
if (core::variant::dispatch_type_builtin_value(type, d))
|
||||
return;
|
||||
|
||||
switch(type.getNamespace())
|
||||
{
|
||||
case 30:
|
||||
{
|
||||
switch (type.getClass())
|
||||
{
|
||||
case 13: return d.template visit<CustomMapType>();
|
||||
}
|
||||
} break;
|
||||
case 64:
|
||||
{
|
||||
switch (type.getClass())
|
||||
{
|
||||
case 23: return d.template visit<Custom>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug_assert(false);
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
bool use_variant_serialization_for(const V &v)
|
||||
{
|
||||
auto primary = vtype_namespace(v.type.id);
|
||||
return primary > 64;
|
||||
}
|
||||
|
||||
bool variant_deserialization_available(VType type)
|
||||
{
|
||||
auto primary = vtype_namespace(type.id);
|
||||
return primary <= 64;
|
||||
}
|
||||
} ;
|
||||
|
||||
struct DispatchVariantHandleExternal : DispatchVariant
|
||||
{
|
||||
template<typename IO>
|
||||
void dispatch_custom(IO &io, VariantIO &v)
|
||||
{
|
||||
core::variant::dispatch_variant(
|
||||
v,
|
||||
*this,
|
||||
io_bin_variant<IO, VariantIO> { io }
|
||||
);
|
||||
}
|
||||
|
||||
template<typename D>
|
||||
void dispatch_primitive(VType type, D &d)
|
||||
{
|
||||
auto ns = type.getNamespace();
|
||||
unused(ns);
|
||||
|
||||
if (core::variant::dispatch_type_builtin_value(type, d))
|
||||
return;
|
||||
|
||||
switch(type.getNamespace())
|
||||
{
|
||||
case 30:
|
||||
{
|
||||
switch (type.getClass())
|
||||
{
|
||||
case 13: return d.template visit<CustomMapType>();
|
||||
}
|
||||
} break;
|
||||
case 64:
|
||||
{
|
||||
switch (type.getClass())
|
||||
{
|
||||
case 23: return d.template visit<Custom>();
|
||||
}
|
||||
}
|
||||
case 65:
|
||||
{
|
||||
switch (type.getClass())
|
||||
{
|
||||
case 33: return d.template visit<External>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug_assert(false);
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
bool use_variant_serialization_for(const V &v)
|
||||
{
|
||||
return v.type.getNamespace() > 64;
|
||||
}
|
||||
|
||||
bool variant_deserialization_available(VType type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
} ;
|
||||
|
||||
struct PoolAllocatorTest
|
||||
{
|
||||
typedef void is_strong_allocator;
|
||||
|
||||
template<typename T>
|
||||
void allocate(T &t)
|
||||
{
|
||||
io_ptr_allocate_default(*this, t);
|
||||
}
|
||||
|
||||
template<typename T, typename ... Args>
|
||||
auto strong(Args && ...args)
|
||||
{
|
||||
return core::strong<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
SCENARIO("core::variant")
|
||||
{
|
||||
GIVEN("nothing")
|
||||
{
|
||||
sLogTest("testing",
|
||||
logVar(sizeof(Variant)) <<
|
||||
logVar(sizeof(Variant::Functional)) <<
|
||||
logVar(sizeof(Variant::value_type)) <<
|
||||
logVar(sizeof(Variant::Type)) <<
|
||||
logVar(sizeof(Variant::Allocator_))
|
||||
);
|
||||
}
|
||||
|
||||
GIVEN("a variant")
|
||||
{
|
||||
Variant v;
|
||||
|
||||
WHEN("variant is set to a unknown")
|
||||
{
|
||||
auto c = External { 5 };
|
||||
v = c;
|
||||
|
||||
constexpr auto cv = vtype_of<External>();
|
||||
constexpr auto cvn = cv.getNamespace();
|
||||
static_assert(cvn == 65);
|
||||
REQUIRE(cv.getNamespace() == 65);
|
||||
|
||||
auto vt = v.type;
|
||||
REQUIRE(vt == cv);
|
||||
|
||||
THEN("unknown is set")
|
||||
{
|
||||
REQUIRE(v.ref<decltype(c)>().x == c.x);
|
||||
}
|
||||
|
||||
WHEN("the variant with unknown is serialized from external -> internal -> internal -> external")
|
||||
{
|
||||
typedef io::bin::Writer<io::bin::memory_out, DispatchVariant> WriterInternal;
|
||||
typedef io::bin::Reader<io::bin::memory_in, DispatchVariant> ReaderInternal;
|
||||
typedef io::bin::Writer<io::bin::memory_out, DispatchVariantHandleExternal> WriterExternal;
|
||||
typedef io::bin::Reader<io::bin::memory_in, DispatchVariantHandleExternal> ReaderExternal;
|
||||
|
||||
WriterExternal wE;
|
||||
auto s1 = io::bin::serializeTo(wE, v);
|
||||
|
||||
ReaderInternal rI({ s1.data(), s1.size() });
|
||||
auto v2 = io::bin::deserializeFrom<Variant>(rI);
|
||||
|
||||
WriterInternal wI;
|
||||
auto s2 = io::bin::serializeTo(wI, v2);
|
||||
|
||||
ReaderExternal rE({ s2.data(), s2.size() });
|
||||
auto v_ = io::bin::deserializeFrom<Variant>(rE);
|
||||
|
||||
THEN("unknown survives")
|
||||
{
|
||||
REQUIRE(v.ref<decltype(c)>().x == c.x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("variant is set to a number")
|
||||
{
|
||||
auto c = 5;
|
||||
v = c;
|
||||
|
||||
THEN("number is set")
|
||||
{
|
||||
REQUIRE(v.ref<decltype(c)>() == c);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("variant is set to a string")
|
||||
{
|
||||
auto c = std::string("hello");
|
||||
v = c;
|
||||
|
||||
THEN("value is set")
|
||||
{
|
||||
REQUIRE(v.ref<decltype(c)>() == c);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("variant is set to a map")
|
||||
{
|
||||
float onePZero = 1.0;
|
||||
double threeP5 = 3.5;
|
||||
|
||||
auto c = CustomMapType();
|
||||
c["hi"] = onePZero;
|
||||
c["there"] = Variant(threeP5);
|
||||
c["what"] = Custom{ .i = 10 };
|
||||
c["recursive"] = CustomMapType { { "a", onePZero }};
|
||||
|
||||
v = c;
|
||||
|
||||
THEN("hi value is set")
|
||||
{
|
||||
auto l = v.ref<decltype(c)>()["hi"].ref<decltype(onePZero)>();
|
||||
auto r = c["hi"].ref<decltype(onePZero)>();
|
||||
|
||||
REQUIRE(l == r);
|
||||
}
|
||||
|
||||
THEN("there value is set")
|
||||
{
|
||||
auto l = v.ref<decltype(c)>()["there"].ref<decltype(threeP5)>();
|
||||
auto r = c["there"].ref<decltype(threeP5)>();
|
||||
|
||||
REQUIRE(l == r);
|
||||
}
|
||||
|
||||
THEN("the value is serialized and deserialized")
|
||||
{
|
||||
typedef io::bin::Writer<io::bin::memory_out, DispatchVariant> Writer;
|
||||
typedef io::bin::Reader<io::bin::memory_in, DispatchVariant> Reader;
|
||||
|
||||
io::bin::Serialization s1;
|
||||
|
||||
Writer w1;
|
||||
s1 = io::bin::serializeTo(w1, v);
|
||||
|
||||
Reader reader({ s1.data(), s1.size() });
|
||||
auto v2 = io::bin::deserializeFrom<Variant>(reader);
|
||||
|
||||
auto &m = v2.ref<CustomMapType>();
|
||||
REQUIRE(m["hi"].ref<decltype(onePZero)>() == onePZero);
|
||||
REQUIRE(m["there"].ref<decltype(threeP5)>() == threeP5);
|
||||
REQUIRE(m["recursive"].ref<CustomMapType>()["a"].ref<decltype(onePZero)>() == onePZero);
|
||||
}
|
||||
|
||||
THEN("the value is serialized deserialized and serialized again")
|
||||
{
|
||||
typedef io::bin::Writer<io::bin::memory_out, DispatchVariant> Writer;
|
||||
typedef io::bin::Reader<io::bin::memory_in, DispatchVariant> Reader;
|
||||
|
||||
io::bin::Serialization s1, s2;
|
||||
|
||||
{
|
||||
Writer w1;
|
||||
s1 = io::bin::serializeTo(w1, v);
|
||||
|
||||
Reader reader({ s1.data(), s1.size() });
|
||||
auto v2 = io::bin::deserializeFrom<Variant>(reader);
|
||||
|
||||
Writer w2;
|
||||
s2 = io::bin::serializeTo(w2, v2);
|
||||
}
|
||||
|
||||
REQUIRE(s1 == s2);
|
||||
}
|
||||
|
||||
|
||||
THEN("the value is serialized deserialized and serialized again with a pool allocator")
|
||||
{
|
||||
typedef io::bin::Writer<io::bin::memory_out, DispatchVariant, PoolAllocatorTest> Writer;
|
||||
typedef io::bin::Reader<io::bin::memory_in, DispatchVariant, PoolAllocatorTest> Reader;
|
||||
|
||||
io::bin::Serialization s1, s2;
|
||||
|
||||
static_assert(allocators::has_allocator<Reader>::value);
|
||||
static_assert(has_variant_allocator<Reader>::value);
|
||||
static_assert(allocators::has_strong_allocator_flag<Reader::Allocator>::value);
|
||||
|
||||
{
|
||||
Writer w1;
|
||||
s1 = io::bin::serializeTo(w1, v);
|
||||
|
||||
Reader reader({ s1.data(), s1.size() });
|
||||
auto v2 = io::bin::deserializeFrom<Variant>(reader);
|
||||
|
||||
Writer w2;
|
||||
s2 = io::bin::serializeTo(w2, v2);
|
||||
}
|
||||
|
||||
REQUIRE(s1 == s2);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user