From 3e4b01d2d2d7e5ed5301c7aacd60ca924addf782 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Mon, 24 May 2021 16:29:58 -0400 Subject: [PATCH 01/23] add sci-seq as fixed length - test --- include/SalmonDefaults.hpp | 1 + include/SingleCellProtocols.hpp | 7 +++++-- src/Alevin.cpp | 8 ++++++++ src/AlevinHash.cpp | 4 ++++ src/AlevinUtils.cpp | 30 ++++++++++++++++++++++++++++++ src/CollapsedCellOptimizer.cpp | 10 ++++++++++ src/GZipWriter.cpp | 7 +++++++ src/ProgramOptionsGenerator.cpp | 3 +++ src/SalmonAlevin.cpp | 15 +++++++++++++++ src/WhiteList.cpp | 4 ++++ 10 files changed, 87 insertions(+), 2 deletions(-) diff --git a/include/SalmonDefaults.hpp b/include/SalmonDefaults.hpp index 333f9da4d..e5d7f1d26 100644 --- a/include/SalmonDefaults.hpp +++ b/include/SalmonDefaults.hpp @@ -140,6 +140,7 @@ namespace defaults { constexpr const bool isCELSeq{false}; constexpr const bool isCELSeq2{false}; constexpr const bool isQuartzSeq2{false}; + constexpr const bool isSciSeq3{false}; constexpr const bool noQuant{false}; constexpr const bool dumpFQ{false}; constexpr const bool dumpArborescences{false}; diff --git a/include/SingleCellProtocols.hpp b/include/SingleCellProtocols.hpp index acc242201..35465e92a 100644 --- a/include/SingleCellProtocols.hpp +++ b/include/SingleCellProtocols.hpp @@ -124,7 +124,7 @@ namespace alevin{ struct InDrop : Rule{ //InDrop starts from 5end with variable //length barcodes so provide the full - // length of the barcod eincluding w1. + // length of the barcode including w1. // UMI length is 6 InDrop(): Rule(42, 6, BarcodeEnd::FIVE, 22347776){} @@ -176,7 +176,10 @@ namespace alevin{ struct Custom : Rule{ Custom() : Rule(0,0,BarcodeEnd::FIVE,0){} }; - + struct SciSeq3 : Rule{ + // Incorrect rule which considers 18 nucleotide barcode and 18 nucleotide UMI + SciSeq3() : Rule(18, 18, BarcodeEnd::FIVE, 1073741824){} + }; // for the new type of specification struct CustomGeometry { diff --git a/src/Alevin.cpp b/src/Alevin.cpp index 1f8ccc218..0b9ccd409 100644 --- a/src/Alevin.cpp +++ b/src/Alevin.cpp @@ -1021,6 +1021,7 @@ salmon-based processing of single-cell RNA-seq data. bool celseq = vm["celseq"].as(); bool celseq2 = vm["celseq2"].as(); bool quartzseq2 = vm["quartzseq2"].as(); + bool sciseq3 = vm["sciseq3"].as(); bool custom_old = vm.count("barcodeLength") and vm.count("umiLength") and vm.count("end"); @@ -1038,6 +1039,7 @@ salmon-based processing of single-cell RNA-seq data. if (celseq) validate_num_protocols += 1; if (celseq2) validate_num_protocols += 1; if (quartzseq2) validate_num_protocols += 1; + // if (sciseq3) validate_num_protocols += 1; if (custom and !noTgMap) validate_num_protocols += 1; if ( validate_num_protocols != 1 ) { @@ -1144,6 +1146,12 @@ salmon-based processing of single-cell RNA-seq data. initiatePipeline(aopt, sopt, orderedOptions, vm, commentString, noTgMap, barcodeFiles, readFiles); + } else if(sciseq3){ + AlevinOpts aopt; + //aopt.jointLog->warn("Using Sci-Seq3 Setting for Alevin"); + initiatePipeline(aopt, sopt, orderedOptions, + vm, commentString, noTgMap, + barcodeFiles, readFiles); } else if (custom_old) { AlevinOpts aopt; //aopt.jointLog->warn("Using Custom Setting for Alevin"); diff --git a/src/AlevinHash.cpp b/src/AlevinHash.cpp index 40bf111b3..09fff9c08 100644 --- a/src/AlevinHash.cpp +++ b/src/AlevinHash.cpp @@ -310,6 +310,10 @@ int salmonHashQuantify(AlevinOpts& aopt, bfs::path& outputDirectory, CFreqMapT& freqCounter); template +int salmonHashQuantify(AlevinOpts& aopt, + bfs::path& outputDirectory, + CFreqMapT& freqCounter); +template int salmonHashQuantify(AlevinOpts& aopt, bfs::path& outputDirectory, CFreqMapT& freqCounter); diff --git a/src/AlevinUtils.cpp b/src/AlevinUtils.cpp index dbc98400e..dfcf5e875 100644 --- a/src/AlevinUtils.cpp +++ b/src/AlevinUtils.cpp @@ -101,6 +101,14 @@ namespace alevin { return &seq2; } template <> + std::string* getReadSequence(apt::SciSeq3& protocol, + std::string& seq, + std::string& seq2, + std::string& subseq){ + (void)seq; + return &seq2; + } + template <> std::string* getReadSequence(apt::Custom& protocol, std::string& seq, std::string& seq2, @@ -223,6 +231,15 @@ namespace alevin { (umi.assign(read, 0, pt.umiLength), true) : false; } template <> + bool extractUMI(std::string& read, + std::string& read2, + apt::SciSeq3& pt, + std::string& umi){ + (void)read2; + return (read.length() >= pt.barcodeLength + pt.umiLength) ? + (umi.assign(read, pt.barcodeLength, pt.umiLength), true) : false; + } + template <> bool extractUMI(std::string& read, std::string& read2, apt::CELSeq& pt, @@ -289,6 +306,15 @@ namespace alevin { (bc.assign(read, 0, pt.barcodeLength), true) : false; } template <> + bool extractBarcode(std::string& read, + std::string& read2, + apt::SciSeq3& pt, + std::string& bc){ + (void)read2; + return (read.length() >= pt.barcodeLength) ? + (bc.assign(read,0, pt.barcodeLength), true) : false; + } + template <> bool extractBarcode(std::string& read, std::string& read2, apt::Custom& pt, @@ -1306,6 +1332,10 @@ namespace alevin { SalmonOpts& sopt, bool noTgMap, boost::program_options::variables_map& vm); template + bool processAlevinOpts(AlevinOpts& aopt, + SalmonOpts& sopt, bool noTgMap, + boost::program_options::variables_map& vm); + template bool processAlevinOpts(AlevinOpts& aopt, SalmonOpts& sopt, bool noTgMap, boost::program_options::variables_map& vm); diff --git a/src/CollapsedCellOptimizer.cpp b/src/CollapsedCellOptimizer.cpp index 06a2fbc95..3fc38e619 100644 --- a/src/CollapsedCellOptimizer.cpp +++ b/src/CollapsedCellOptimizer.cpp @@ -1516,6 +1516,16 @@ bool CollapsedCellOptimizer::optimize(EqMapT& fullEqMap, CFreqMapT& freqCounter, size_t numLowConfidentBarcode); +template +bool CollapsedCellOptimizer::optimize(EqMapT& fullEqMap, + spp::sparse_hash_map& txpToGeneMap, + spp::sparse_hash_map& geneIdxMap, + AlevinOpts& aopt, + GZipWriter& gzw, + std::vector& trueBarcodes, + std::vector& umiCount, + CFreqMapT& freqCounter, + size_t numLowConfidentBarcode); template bool CollapsedCellOptimizer::optimize(EqMapT& fullEqMap, diff --git a/src/GZipWriter.cpp b/src/GZipWriter.cpp index f3ce91d0b..c0f8e6b35 100644 --- a/src/GZipWriter.cpp +++ b/src/GZipWriter.cpp @@ -1810,6 +1810,10 @@ bool GZipWriter::writeEquivCounts( const AlevinOpts& aopts, SCExpT& readExp); template +bool GZipWriter::writeEquivCounts( + const AlevinOpts& aopts, + SCExpT& readExp); +template bool GZipWriter::writeEquivCounts( const AlevinOpts& aopts, SCExpT& readExp); @@ -1842,6 +1846,9 @@ template bool GZipWriter::writeMetaAlevin(const AlevinOpts& opts, boost::filesystem::path aux_dir); template bool +GZipWriter::writeMetaAlevin(const AlevinOpts& opts, + boost::filesystem::path aux_dir); +template bool GZipWriter::writeMetaAlevin(const AlevinOpts& opts, boost::filesystem::path aux_dir); template bool diff --git a/src/ProgramOptionsGenerator.cpp b/src/ProgramOptionsGenerator.cpp index d3a4f22da..98cd40927 100644 --- a/src/ProgramOptionsGenerator.cpp +++ b/src/ProgramOptionsGenerator.cpp @@ -413,6 +413,9 @@ namespace salmon { ( "quartzseq2", po::bool_switch()->default_value(alevin::defaults::isQuartzSeq2), "Use Quartz-Seq2 v3.2 Single Cell protocol for the library assumes 15 length barcode and 8 length UMI.") + ( + "sciseq3", po::bool_switch()->default_value(alevin::defaults::isSciSeq3), + "Use sci-RNA-seq3 protocol for the library.") ( "whitelist", po::value(), "File containing white-list barcodes") diff --git a/src/SalmonAlevin.cpp b/src/SalmonAlevin.cpp index 88b1d5c2e..5d5b28689 100644 --- a/src/SalmonAlevin.cpp +++ b/src/SalmonAlevin.cpp @@ -3118,6 +3118,21 @@ int alevinQuant(AlevinOpts& aopt, CFreqMapT& freqCounter, size_t numLowConfidentBarcode); +template +int alevin_sc_align(AlevinOpts& aopt, + SalmonOpts& sopt, + boost::program_options::parsed_options& orderedOptions); +template +int alevinQuant(AlevinOpts& aopt, + SalmonOpts& sopt, + SoftMapT& barcodeMap, + TrueBcsT& trueBarcodes, + spp::sparse_hash_map& txpToGeneMap, + spp::sparse_hash_map& geneIdxMap, + boost::program_options::parsed_options& orderedOptions, + CFreqMapT& freqCounter, + size_t numLowConfidentBarcode); + template int alevin_sc_align(AlevinOpts& aopt, SalmonOpts& sopt, diff --git a/src/WhiteList.cpp b/src/WhiteList.cpp index cef7c9acf..91dd62e68 100644 --- a/src/WhiteList.cpp +++ b/src/WhiteList.cpp @@ -288,6 +288,10 @@ namespace alevin { std::vector& trueBarcodes, bool useRibo, bool useMito, size_t numLowConfidentBarcode); + template bool performWhitelisting(AlevinOpts& aopt, + std::vector& trueBarcodes, + bool useRibo, bool useMito, + size_t numLowConfidentBarcode); template bool performWhitelisting(AlevinOpts& aopt, std::vector& trueBarcodes, bool useRibo, bool useMito, From 4f131ca9b53580fa37c1e4029cf651a90972d2cb Mon Sep 17 00:00:00 2001 From: Gaurav Date: Thu, 3 Jun 2021 09:49:06 -0400 Subject: [PATCH 02/23] add sci-seq3 as protocol --- src/Alevin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Alevin.cpp b/src/Alevin.cpp index 0b9ccd409..318133578 100644 --- a/src/Alevin.cpp +++ b/src/Alevin.cpp @@ -1039,7 +1039,7 @@ salmon-based processing of single-cell RNA-seq data. if (celseq) validate_num_protocols += 1; if (celseq2) validate_num_protocols += 1; if (quartzseq2) validate_num_protocols += 1; - // if (sciseq3) validate_num_protocols += 1; + if (sciseq3) validate_num_protocols += 1; if (custom and !noTgMap) validate_num_protocols += 1; if ( validate_num_protocols != 1 ) { From 184abcd62482dfd65d896f95cace15be56f20ca7 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Wed, 9 Jun 2021 12:21:49 -0400 Subject: [PATCH 03/23] extact barcode and UMI from sci-rna-seq3 (wip) - error with alevin-fry reading rad --- include/SingleCellProtocols.hpp | 6 +++++- src/AlevinUtils.cpp | 21 ++++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/include/SingleCellProtocols.hpp b/include/SingleCellProtocols.hpp index 35465e92a..e9ec4e579 100644 --- a/include/SingleCellProtocols.hpp +++ b/include/SingleCellProtocols.hpp @@ -178,7 +178,11 @@ namespace alevin{ }; struct SciSeq3 : Rule{ // Incorrect rule which considers 18 nucleotide barcode and 18 nucleotide UMI - SciSeq3() : Rule(18, 18, BarcodeEnd::FIVE, 1073741824){} + SciSeq3() : Rule(20, 8, BarcodeEnd::FIVE, 1073741824){} + std::string anchorSeq = "CAGAGC"; + std::size_t anchorSeqLen = anchorSeq.length(); + u_int16_t const maxHairpinIndexLen = 10; + u_int16_t const rtIdxLen = 10; }; // for the new type of specification diff --git a/src/AlevinUtils.cpp b/src/AlevinUtils.cpp index dfcf5e875..a35ed7845 100644 --- a/src/AlevinUtils.cpp +++ b/src/AlevinUtils.cpp @@ -236,8 +236,10 @@ namespace alevin { apt::SciSeq3& pt, std::string& umi){ (void)read2; - return (read.length() >= pt.barcodeLength + pt.umiLength) ? - (umi.assign(read, pt.barcodeLength, pt.umiLength), true) : false; + std::size_t index = read.find(pt.anchorSeq); + return (read.length() >= pt.barcodeLength + pt.umiLength && + index != std::string::npos) ? + (umi.assign(read, index + pt.anchorSeqLen, pt.umiLength), true) : false; } template <> bool extractUMI(std::string& read, @@ -246,7 +248,7 @@ namespace alevin { std::string& umi){ (void)read2; return (read.length() >= pt.umiLength) ? - (umi.assign(read, 0, pt.umiLength), true) : false; + (umi.assign(read, pt.barcodeLength, pt.umiLength), true) : false; return true; } template <> @@ -311,8 +313,17 @@ namespace alevin { apt::SciSeq3& pt, std::string& bc){ (void)read2; - return (read.length() >= pt.barcodeLength) ? - (bc.assign(read,0, pt.barcodeLength), true) : false; + std::string::size_type index = read.find(pt.anchorSeq); + if (index != std::string::npos && ( index == pt.maxHairpinIndexLen || index == pt.maxHairpinIndexLen -1) // only 2 possible values of index + && read.length() >= pt.barcodeLength + pt.umiLength + pt.anchorSeqLen) { + if (index < pt.maxHairpinIndexLen) { // hairpin index can be 9 or 10 bp + bc = bc.substr(1,bc.length()); + } + bc.assign(read.substr(0,index) + read.substr(index + pt.anchorSeqLen + pt.umiLength, pt.rtIdxLen)); + return true; + } else { + return false; + } } template <> bool extractBarcode(std::string& read, From 6ddbae869700428725d55301fb9fd9fdb0aab458 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Mon, 21 Jun 2021 15:41:22 -0400 Subject: [PATCH 04/23] modify extractBarcode - add extra A if len <20 --- include/SingleCellProtocols.hpp | 3 +-- src/AlevinUtils.cpp | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/SingleCellProtocols.hpp b/include/SingleCellProtocols.hpp index e9ec4e579..814c9cebe 100644 --- a/include/SingleCellProtocols.hpp +++ b/include/SingleCellProtocols.hpp @@ -177,12 +177,11 @@ namespace alevin{ Custom() : Rule(0,0,BarcodeEnd::FIVE,0){} }; struct SciSeq3 : Rule{ - // Incorrect rule which considers 18 nucleotide barcode and 18 nucleotide UMI SciSeq3() : Rule(20, 8, BarcodeEnd::FIVE, 1073741824){} std::string anchorSeq = "CAGAGC"; std::size_t anchorSeqLen = anchorSeq.length(); u_int16_t const maxHairpinIndexLen = 10; - u_int16_t const rtIdxLen = 10; + u_int16_t const rtIdxLen = 10; // rev transcription index length }; // for the new type of specification diff --git a/src/AlevinUtils.cpp b/src/AlevinUtils.cpp index a35ed7845..7cc01d517 100644 --- a/src/AlevinUtils.cpp +++ b/src/AlevinUtils.cpp @@ -316,10 +316,12 @@ namespace alevin { std::string::size_type index = read.find(pt.anchorSeq); if (index != std::string::npos && ( index == pt.maxHairpinIndexLen || index == pt.maxHairpinIndexLen -1) // only 2 possible values of index && read.length() >= pt.barcodeLength + pt.umiLength + pt.anchorSeqLen) { + std::string bcAssign = read.substr(0,index) + read.substr(index + pt.anchorSeqLen + pt.umiLength, pt.rtIdxLen); if (index < pt.maxHairpinIndexLen) { // hairpin index can be 9 or 10 bp bc = bc.substr(1,bc.length()); + bcAssign += "A"; } - bc.assign(read.substr(0,index) + read.substr(index + pt.anchorSeqLen + pt.umiLength, pt.rtIdxLen)); + bc.assign(bcAssign); return true; } else { return false; From 2677496f6701a9b93aef55fbefaa553d236ca7b1 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Wed, 4 Aug 2021 18:11:51 -0400 Subject: [PATCH 05/23] find anchorbarcode only once by creating thread copy of protocol --- include/SingleCellProtocols.hpp | 1 + src/AlevinUtils.cpp | 13 ++++++------- src/SalmonAlevin.cpp | 29 +++++++++++++++-------------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/include/SingleCellProtocols.hpp b/include/SingleCellProtocols.hpp index 814c9cebe..df538d3f2 100644 --- a/include/SingleCellProtocols.hpp +++ b/include/SingleCellProtocols.hpp @@ -180,6 +180,7 @@ namespace alevin{ SciSeq3() : Rule(20, 8, BarcodeEnd::FIVE, 1073741824){} std::string anchorSeq = "CAGAGC"; std::size_t anchorSeqLen = anchorSeq.length(); + std::size_t anchorPos = 0; u_int16_t const maxHairpinIndexLen = 10; u_int16_t const rtIdxLen = 10; // rev transcription index length }; diff --git a/src/AlevinUtils.cpp b/src/AlevinUtils.cpp index 7cc01d517..7fa90c4ad 100644 --- a/src/AlevinUtils.cpp +++ b/src/AlevinUtils.cpp @@ -236,10 +236,9 @@ namespace alevin { apt::SciSeq3& pt, std::string& umi){ (void)read2; - std::size_t index = read.find(pt.anchorSeq); return (read.length() >= pt.barcodeLength + pt.umiLength && - index != std::string::npos) ? - (umi.assign(read, index + pt.anchorSeqLen, pt.umiLength), true) : false; + pt.anchorPos != std::string::npos) ? // for the rare case if barcode has one N and thus gets recovered + (umi.assign(read, pt.anchorPos + pt.anchorSeqLen, pt.umiLength), true) : false; } template <> bool extractUMI(std::string& read, @@ -313,11 +312,11 @@ namespace alevin { apt::SciSeq3& pt, std::string& bc){ (void)read2; - std::string::size_type index = read.find(pt.anchorSeq); - if (index != std::string::npos && ( index == pt.maxHairpinIndexLen || index == pt.maxHairpinIndexLen -1) // only 2 possible values of index + pt.anchorPos = read.find(pt.anchorSeq); + if (pt.anchorPos != std::string::npos && ( pt.anchorPos == pt.maxHairpinIndexLen || pt.anchorPos == pt.maxHairpinIndexLen -1) // only 2 possible values of pt.anchorPos && read.length() >= pt.barcodeLength + pt.umiLength + pt.anchorSeqLen) { - std::string bcAssign = read.substr(0,index) + read.substr(index + pt.anchorSeqLen + pt.umiLength, pt.rtIdxLen); - if (index < pt.maxHairpinIndexLen) { // hairpin index can be 9 or 10 bp + std::string bcAssign = read.substr(0,pt.anchorPos) + read.substr(pt.anchorPos + pt.anchorSeqLen + pt.umiLength, pt.rtIdxLen); + if (pt.anchorPos < pt.maxHairpinIndexLen) { // hairpin index can be 9 or 10 bp bc = bc.substr(1,bc.length()); bcAssign += "A"; } diff --git a/src/SalmonAlevin.cpp b/src/SalmonAlevin.cpp index 5d5b28689..572334e73 100644 --- a/src/SalmonAlevin.cpp +++ b/src/SalmonAlevin.cpp @@ -150,7 +150,7 @@ namespace alevin{ constexpr uint32_t miniBatchSize{5000}; using CellBarcodeT = uint32_t; - using UMIBarcodeT = uint64_t; + using UMIBarcodeT = uint32_t; template using AlevinAlnGroup = AlignmentGroup; template using AlnGroupVec = std::vector>; @@ -663,7 +663,8 @@ void process_reads_sc_sketch(paired_parser* parser, ReadExperimentT& readExp, Re if (alevinOpts.protocol.end == bcEnd::FIVE || alevinOpts.protocol.end == bcEnd::THREE){ - bool extracted_bc = aut::extractBarcode(rp.first.seq, rp.second.seq, alevinOpts.protocol, barcode); + auto localProtocol = alevinOpts.protocol; + bool extracted_bc = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); seqOk = (extracted_bc) ? aut::sequenceCheck(barcode, Sequence::BARCODE) : false; @@ -674,8 +675,7 @@ void process_reads_sc_sketch(paired_parser* parser, ReadExperimentT& readExp, Re // If we have a valid barcode if (seqOk) { - bool umi_ok = aut::extractUMI(rp.first.seq, rp.second.seq, alevinOpts.protocol, umi); - //aopt.jointLog->info("BC : {}, UMI : {}". barcode, umi); + bool umi_ok = aut::extractUMI(rp.first.seq, rp.second.seq, localProtocol, umi); if ( !umi_ok ) { smallSeqs += 1; } else { @@ -907,11 +907,11 @@ void process_reads_sc_sketch(paired_parser* parser, ReadExperimentT& readExp, Re } // umi - if ( alevinOpts.protocol.barcodeLength <= 16 ) { // if we can use 32-bit int + if ( alevinOpts.protocol.umiLength <= 16 ) { // if we can use 32-bit int uint64_t umiint = jointHitGroup.umi(); uint32_t shortumi = static_cast(0x00000000FFFFFFFF & umiint); bw << shortumi; - } else if ( alevinOpts.protocol.barcodeLength <= 32 ) { // if we can use 64-bit int + } else if ( alevinOpts.protocol.umiLength <= 32 ) { // if we can use 64-bit int uint64_t umiint = jointHitGroup.umi(); bw << umiint; } else { // must use string @@ -1182,7 +1182,8 @@ void process_reads_sc_align(paired_parser* parser, ReadExperimentT& readExp, Rea if (alevinOpts.protocol.end == bcEnd::FIVE || alevinOpts.protocol.end == bcEnd::THREE){ - bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, alevinOpts.protocol, barcode); + auto localProtocol = alevinOpts.protocol; + bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); seqOk = (extracted_barcode) ? aut::sequenceCheck(barcode, Sequence::BARCODE) : false; @@ -1193,8 +1194,7 @@ void process_reads_sc_align(paired_parser* parser, ReadExperimentT& readExp, Rea // If we have a valid barcode if (seqOk) { - bool umi_ok = aut::extractUMI(rp.first.seq, rp.second.seq, alevinOpts.protocol, umi); - + bool umi_ok = aut::extractUMI(rp.first.seq, rp.second.seq, localProtocol, umi); if ( !umi_ok ) { smallSeqs += 1; } else { @@ -1351,11 +1351,11 @@ void process_reads_sc_align(paired_parser* parser, ReadExperimentT& readExp, Rea } // umi - if ( alevinOpts.protocol.barcodeLength <= 16 ) { // if we can use 32-bit int + if ( alevinOpts.protocol.umiLength <= 16 ) { // if we can use 32-bit int uint64_t umiint = jointHitGroup.umi(); uint32_t shortumi = static_cast(0x00000000FFFFFFFF & umiint); bw << shortumi; - } else if ( alevinOpts.protocol.barcodeLength <= 32 ) { // if we can use 64-bit int + } else if ( alevinOpts.protocol.umiLength <= 32 ) { // if we can use 64-bit int uint64_t umiint = jointHitGroup.umi(); bw << umiint; } else { // must use string @@ -1374,7 +1374,7 @@ void process_reads_sc_align(paired_parser* parser, ReadExperimentT& readExp, Rea } else { if (barcode_ok) { unmapped_bc_map[bck.word(0)] += 1; - } + } } @@ -1640,7 +1640,8 @@ void processReadsQuasi( if (alevinOpts.protocol.end == bcEnd::FIVE || alevinOpts.protocol.end == bcEnd::THREE){ - bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, alevinOpts.protocol, barcode); + auto localProtocol = alevinOpts.protocol; + bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); seqOk = (extracted_barcode) ? aut::sequenceCheck(barcode, Sequence::BARCODE) : false; @@ -1684,7 +1685,7 @@ void processReadsQuasi( if (barcodeIdx) { //corrBarcodeIndex = barcodeMap[barcodeIndex]; jointHitGroup.setBarcode(*barcodeIdx); - bool umi_ok = aut::extractUMI(rp.first.seq, rp.second.seq, alevinOpts.protocol, umi); + bool umi_ok = aut::extractUMI(rp.first.seq, rp.second.seq, localProtocol, umi); if ( !umi_ok ) { smallSeqs += 1; From 9f3dfa7a9f5e14318fc49169987e9f308c5375ee Mon Sep 17 00:00:00 2001 From: Gaurav Date: Thu, 9 Sep 2021 16:53:15 -0400 Subject: [PATCH 06/23] revive indrop in alevin --- include/SingleCellProtocols.hpp | 6 +++++- src/Alevin.cpp | 2 -- src/AlevinUtils.cpp | 17 +++++++++++------ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/include/SingleCellProtocols.hpp b/include/SingleCellProtocols.hpp index 252f8d4a6..24ec02e0c 100644 --- a/include/SingleCellProtocols.hpp +++ b/include/SingleCellProtocols.hpp @@ -129,12 +129,16 @@ namespace alevin{ //length barcodes so provide the full // length of the barcod eincluding w1. // UMI length is 6 - InDrop(): Rule(42, 6, BarcodeEnd::FIVE, 22347776){} + InDrop(): Rule(19, 6, BarcodeEnd::FIVE, 22347776){} std::string w1; + std::size_t w1Length; void setW1(std::string& w1_){ w1 = w1_; + w1Length = w1.length(); } + std::size_t w1Pos = 0, bc2EndPos; + }; struct CITESeq : Rule{ diff --git a/src/Alevin.cpp b/src/Alevin.cpp index 9debe68fa..09cd0b049 100644 --- a/src/Alevin.cpp +++ b/src/Alevin.cpp @@ -1080,8 +1080,6 @@ salmon-based processing of single-cell RNA-seq data. barcodeFiles, readFiles); } else if(indrop){ - std::cout<<"Indrop get neighbors removed, please use other protocols"; - exit(1); if(vm.count("w1") != 0){ std::string w1 = vm["w1"].as(); AlevinOpts aopt; diff --git a/src/AlevinUtils.cpp b/src/AlevinUtils.cpp index dbc98400e..02d980a66 100644 --- a/src/AlevinUtils.cpp +++ b/src/AlevinUtils.cpp @@ -237,10 +237,10 @@ namespace alevin { std::string& read2, apt::InDrop& pt, std::string& umi){ - (void)read; (void)read2; - std::cout<<"Incorrect call for umi extract"; - exit(1); + return (read.length() >= pt.umiLength) ? + (umi.assign(read, pt.bc2EndPos, pt.bc2EndPos+6), true) : false; + return true; } template <> @@ -343,17 +343,22 @@ namespace alevin { std::string& read2, apt::InDrop& pt, std::string& bc){ (void)read2; - std::string::size_type index = read.find(pt.w1); - if (index == std::string::npos){ + if(read.length() >= (pt.w1Length + pt.barcodeLength + pt.umiLength)) { + pt.w1Pos = read.find(pt.w1); + if (pt.w1Pos == std::string::npos){ return false; } - bc = read.substr(0, index); + bc = read.substr(0, pt.w1Pos); if(bc.size()<8 or bc.size()>12){ return false; } uint32_t offset = bc.size()+pt.w1.size(); bc += read.substr(offset, offset+8); + pt.bc2EndPos = offset+8; return true; + } else { + return false; + } } void getIndelNeighbors( From 5dc5d3689715bad6a26c3f9eab170adf11fa7aab Mon Sep 17 00:00:00 2001 From: Gaurav Date: Thu, 9 Sep 2021 16:58:33 -0400 Subject: [PATCH 07/23] add localProtocol to share protocol data within thread --- src/SalmonAlevin.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/SalmonAlevin.cpp b/src/SalmonAlevin.cpp index 535876f10..855ead5a1 100644 --- a/src/SalmonAlevin.cpp +++ b/src/SalmonAlevin.cpp @@ -671,7 +671,8 @@ void process_reads_sc_sketch(paired_parser* parser, ReadExperimentT& readExp, Re if (alevinOpts.protocol.end == bcEnd::FIVE || alevinOpts.protocol.end == bcEnd::THREE){ - bool extracted_bc = aut::extractBarcode(rp.first.seq, rp.second.seq, alevinOpts.protocol, barcode); + auto localProtocol = alevinOpts.protocol; + bool extracted_bc = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); seqOk = (extracted_bc) ? aut::sequenceCheck(barcode, Sequence::BARCODE) : false; @@ -682,7 +683,7 @@ void process_reads_sc_sketch(paired_parser* parser, ReadExperimentT& readExp, Re // If we have a valid barcode if (seqOk) { - bool umi_ok = aut::extractUMI(rp.first.seq, rp.second.seq, alevinOpts.protocol, umi); + bool umi_ok = aut::extractUMI(rp.first.seq, rp.second.seq, localProtocol, umi); //aopt.jointLog->info("BC : {}, UMI : {}". barcode, umi); if ( !umi_ok ) { smallSeqs += 1; @@ -1192,7 +1193,8 @@ void process_reads_sc_align(paired_parser* parser, ReadExperimentT& readExp, Rea if (alevinOpts.protocol.end == bcEnd::FIVE || alevinOpts.protocol.end == bcEnd::THREE){ - bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, alevinOpts.protocol, barcode); + auto localProtocol = alevinOpts.protocol; + bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); seqOk = (extracted_barcode) ? aut::sequenceCheck(barcode, Sequence::BARCODE) : false; @@ -1203,7 +1205,7 @@ void process_reads_sc_align(paired_parser* parser, ReadExperimentT& readExp, Rea // If we have a valid barcode if (seqOk) { - bool umi_ok = aut::extractUMI(rp.first.seq, rp.second.seq, alevinOpts.protocol, umi); + bool umi_ok = aut::extractUMI(rp.first.seq, rp.second.seq, localProtocol, umi); if ( !umi_ok ) { smallSeqs += 1; @@ -1650,7 +1652,8 @@ void processReadsQuasi( if (alevinOpts.protocol.end == bcEnd::FIVE || alevinOpts.protocol.end == bcEnd::THREE){ - bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, alevinOpts.protocol, barcode); + auto localProtocol = alevinOpts.protocol; + bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); seqOk = (extracted_barcode) ? aut::sequenceCheck(barcode, Sequence::BARCODE) : false; @@ -1694,7 +1697,7 @@ void processReadsQuasi( if (barcodeIdx) { //corrBarcodeIndex = barcodeMap[barcodeIndex]; jointHitGroup.setBarcode(*barcodeIdx); - bool umi_ok = aut::extractUMI(rp.first.seq, rp.second.seq, alevinOpts.protocol, umi); + bool umi_ok = aut::extractUMI(rp.first.seq, rp.second.seq, localProtocol, umi); if ( !umi_ok ) { smallSeqs += 1; From cc1cd67ffe00af761ba2b02362d4f1b378928ac4 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 10 Sep 2021 16:36:48 -0400 Subject: [PATCH 08/23] modify indrop protocol: - add padding with A to make bc len constant - if w1 not found search with hamming distance 2 --- include/AlevinUtils.hpp | 3 +++ include/SingleCellProtocols.hpp | 3 +-- src/AlevinUtils.cpp | 27 +++++++++++++++++++++++---- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/include/AlevinUtils.hpp b/include/AlevinUtils.hpp index c22bf0c1a..6b36c12f7 100644 --- a/include/AlevinUtils.hpp +++ b/include/AlevinUtils.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include "spdlog/spdlog.h" @@ -72,6 +73,8 @@ namespace alevin{ void readWhitelist(bfs::path& filePath, TrueBcsT& trueBarcodes); + unsigned int hammingDistance(const std::string s1, const std::string s2); + template bool processAlevinOpts(AlevinOpts& aopt, SalmonOpts& sopt, bool noTgMap, diff --git a/include/SingleCellProtocols.hpp b/include/SingleCellProtocols.hpp index 24ec02e0c..5b1175a8c 100644 --- a/include/SingleCellProtocols.hpp +++ b/include/SingleCellProtocols.hpp @@ -132,13 +132,12 @@ namespace alevin{ InDrop(): Rule(19, 6, BarcodeEnd::FIVE, 22347776){} std::string w1; - std::size_t w1Length; + std::size_t w1Length, maxHammingDist = 2; void setW1(std::string& w1_){ w1 = w1_; w1Length = w1.length(); } std::size_t w1Pos = 0, bc2EndPos; - }; struct CITESeq : Rule{ diff --git a/src/AlevinUtils.cpp b/src/AlevinUtils.cpp index 02d980a66..28ab33a72 100644 --- a/src/AlevinUtils.cpp +++ b/src/AlevinUtils.cpp @@ -239,7 +239,7 @@ namespace alevin { std::string& umi){ (void)read2; return (read.length() >= pt.umiLength) ? - (umi.assign(read, pt.bc2EndPos, pt.bc2EndPos+6), true) : false; + (umi.assign(read, pt.bc2EndPos, pt.umiLength), true) : false; return true; } @@ -346,14 +346,23 @@ namespace alevin { if(read.length() >= (pt.w1Length + pt.barcodeLength + pt.umiLength)) { pt.w1Pos = read.find(pt.w1); if (pt.w1Pos == std::string::npos){ - return false; + bool found = false; + for( int i = 8; i <= 11; i++){ + if (hammingDistance(pt.w1, read.substr(i,pt.w1Length)) <= pt.maxHammingDist) { + pt.w1Pos = i; + found = true; + break; + } + } + if (!found) {return false;} } bc = read.substr(0, pt.w1Pos); - if(bc.size()<8 or bc.size()>12){ + if(bc.size()<8 or bc.size()>11){ return false; } uint32_t offset = bc.size()+pt.w1.size(); - bc += read.substr(offset, offset+8); + bc += read.substr(offset, 8); + bc += std::string(pt.barcodeLength - bc.size(), 'A'); pt.bc2EndPos = offset+8; return true; } else { @@ -442,6 +451,16 @@ namespace alevin { neighbors); } + unsigned int hammingDistance(const std::string s1, const std::string s2){ + if(s1.size() != s2.size()){ + throw std::invalid_argument("Strings have different lengths, can't compute hamming distance"); + } + + // compute dot product for all postisions, start with 0 and add if the values are not equal + return std::inner_product(s1.begin(),s1.end(),s2.begin(), 0, std::plus(), + std::not2(std::equal_to())); + } + void getTxpToGeneMap(spp::sparse_hash_map& txpToGeneMap, spp::sparse_hash_map& geneIdxMap, const std::string& t2gFileName, From 4a7f60a1861c333ea0eeed09ac79a22cc7dc7c63 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Wed, 15 Sep 2021 20:12:52 -0400 Subject: [PATCH 09/23] specify indropV2 and swap read1 and read2 acc to protocol --- include/SingleCellProtocols.hpp | 10 +++++----- src/Alevin.cpp | 14 +++++++------- src/AlevinHash.cpp | 2 +- src/AlevinUtils.cpp | 34 ++++++++++++++++----------------- src/CollapsedCellOptimizer.cpp | 2 +- src/GZipWriter.cpp | 6 +++--- src/ProgramOptionsGenerator.cpp | 4 ++-- src/SalmonAlevin.cpp | 4 ++-- src/WhiteList.cpp | 2 +- 9 files changed, 39 insertions(+), 39 deletions(-) diff --git a/include/SingleCellProtocols.hpp b/include/SingleCellProtocols.hpp index 5b1175a8c..72836560c 100644 --- a/include/SingleCellProtocols.hpp +++ b/include/SingleCellProtocols.hpp @@ -124,12 +124,12 @@ namespace alevin{ DropSeq(): Rule(12, 8, BarcodeEnd::FIVE, 16777216){} }; - struct InDrop : Rule{ - //InDrop starts from 5end with variable - //length barcodes so provide the full - // length of the barcod eincluding w1. + struct InDropV2 : Rule{ + //InDropV2 starts from 5end with variable + //length barcodes that varies from 8 to 11 bp + // so provide the full length of the barcode // UMI length is 6 - InDrop(): Rule(19, 6, BarcodeEnd::FIVE, 22347776){} + InDropV2(): Rule(19, 6, BarcodeEnd::FIVE, 22347776){} std::string w1; std::size_t w1Length, maxHammingDist = 2; diff --git a/src/Alevin.cpp b/src/Alevin.cpp index 09cd0b049..347c99ecd 100644 --- a/src/Alevin.cpp +++ b/src/Alevin.cpp @@ -1022,7 +1022,7 @@ salmon-based processing of single-cell RNA-seq data. bool noTgMap {false}; bool dropseq = vm["dropseq"].as(); - bool indrop = vm["indrop"].as(); + bool indropV2 = vm["indropV2"].as(); bool citeseq = vm["citeseq"].as(); bool chromV3 = vm["chromiumV3"].as(); bool chrom = vm["chromium"].as(); @@ -1039,7 +1039,7 @@ salmon-based processing of single-cell RNA-seq data. uint8_t validate_num_protocols {0}; if (dropseq) validate_num_protocols += 1; - if (indrop) validate_num_protocols += 1; + if (indropV2) validate_num_protocols += 1; if (citeseq) { validate_num_protocols += 1; noTgMap = true;} if (chromV3) validate_num_protocols += 1; if (chrom) validate_num_protocols += 1; @@ -1079,18 +1079,18 @@ salmon-based processing of single-cell RNA-seq data. vm, commentString, noTgMap, barcodeFiles, readFiles); } - else if(indrop){ + else if(indropV2){ if(vm.count("w1") != 0){ std::string w1 = vm["w1"].as(); - AlevinOpts aopt; + AlevinOpts aopt; aopt.protocol.setW1(w1); - //aopt.jointLog->warn("Using InDrop Setting for Alevin"); + //aopt.jointLog->warn("Using InDropV2 Setting for Alevin"); initiatePipeline(aopt, sopt, orderedOptions, vm, commentString, noTgMap, barcodeFiles, readFiles); } else{ - fmt::print(stderr, "ERROR: indrop needs w1 flag too.\n Exiting Now"); + fmt::print(stderr, "ERROR: indropV2 needs w1 flag too.\n Exiting Now"); exit(1); } } @@ -1100,7 +1100,7 @@ salmon-based processing of single-cell RNA-seq data. aopt.protocol.setFeatureLength(vm["featureLength"].as()); aopt.protocol.setFeatureStart(vm["featureStart"].as()); - //aopt.jointLog->warn("Using InDrop Setting for Alevin"); + //aopt.jointLog->warn("Using InDropV2 Setting for Alevin"); initiatePipeline(aopt, sopt, orderedOptions, vm, commentString, noTgMap, barcodeFiles, readFiles); diff --git a/src/AlevinHash.cpp b/src/AlevinHash.cpp index 40bf111b3..99a125b49 100644 --- a/src/AlevinHash.cpp +++ b/src/AlevinHash.cpp @@ -294,7 +294,7 @@ int salmonHashQuantify(AlevinOpts& aopt, bfs::path& outputDirectory, CFreqMapT& freqCounter); template -int salmonHashQuantify(AlevinOpts& aopt, +int salmonHashQuantify(AlevinOpts& aopt, bfs::path& outputDirectory, CFreqMapT& freqCounter); template diff --git a/src/AlevinUtils.cpp b/src/AlevinUtils.cpp index 28ab33a72..06bb4b630 100644 --- a/src/AlevinUtils.cpp +++ b/src/AlevinUtils.cpp @@ -126,12 +126,12 @@ namespace alevin { return &seq2; } template <> - std::string* getReadSequence(apt::InDrop& protocol, + std::string* getReadSequence(apt::InDropV2& protocol, std::string& seq, std::string& seq2, std::string& subseq){ - (void)seq; - return &seq2; + (void)seq2; + return &seq; } // end of read extraction @@ -233,13 +233,13 @@ namespace alevin { return true; } template <> - bool extractUMI(std::string& read, + bool extractUMI(std::string& read, std::string& read2, - apt::InDrop& pt, + apt::InDropV2& pt, std::string& umi){ - (void)read2; - return (read.length() >= pt.umiLength) ? - (umi.assign(read, pt.bc2EndPos, pt.umiLength), true) : false; + (void)read; + return (read2.length() >= pt.umiLength) ? + (umi.assign(read2, pt.bc2EndPos, pt.umiLength), true) : false; return true; } @@ -339,16 +339,16 @@ namespace alevin { (bc.assign(read, pt.umiLength, pt.barcodeLength), true) : false; } template <> - bool extractBarcode(std::string& read, + bool extractBarcode(std::string& read, std::string& read2, - apt::InDrop& pt, std::string& bc){ - (void)read2; - if(read.length() >= (pt.w1Length + pt.barcodeLength + pt.umiLength)) { - pt.w1Pos = read.find(pt.w1); + apt::InDropV2& pt, std::string& bc){ + (void)read; + if(read2.length() >= (pt.w1Length + pt.barcodeLength + pt.umiLength)) { + pt.w1Pos = read2.find(pt.w1); if (pt.w1Pos == std::string::npos){ bool found = false; for( int i = 8; i <= 11; i++){ - if (hammingDistance(pt.w1, read.substr(i,pt.w1Length)) <= pt.maxHammingDist) { + if (hammingDistance(pt.w1, read2.substr(i,pt.w1Length)) <= pt.maxHammingDist) { pt.w1Pos = i; found = true; break; @@ -356,12 +356,12 @@ namespace alevin { } if (!found) {return false;} } - bc = read.substr(0, pt.w1Pos); + bc = read2.substr(0, pt.w1Pos); if(bc.size()<8 or bc.size()>11){ return false; } uint32_t offset = bc.size()+pt.w1.size(); - bc += read.substr(offset, 8); + bc += read2.substr(offset, 8); bc += std::string(pt.barcodeLength - bc.size(), 'A'); pt.bc2EndPos = offset+8; return true; @@ -1298,7 +1298,7 @@ namespace alevin { SalmonOpts& sopt, bool noTgMap, boost::program_options::variables_map& vm); template - bool processAlevinOpts(AlevinOpts& aopt, + bool processAlevinOpts(AlevinOpts& aopt, SalmonOpts& sopt, bool noTgMap, boost::program_options::variables_map& vm); template diff --git a/src/CollapsedCellOptimizer.cpp b/src/CollapsedCellOptimizer.cpp index 06a2fbc95..de6ec7d1c 100644 --- a/src/CollapsedCellOptimizer.cpp +++ b/src/CollapsedCellOptimizer.cpp @@ -1438,7 +1438,7 @@ template bool CollapsedCellOptimizer::optimize(EqMapT& fullEqMap, spp::sparse_hash_map& txpToGeneMap, spp::sparse_hash_map& geneIdxMap, - AlevinOpts& aopt, + AlevinOpts& aopt, GZipWriter& gzw, std::vector& trueBarcodes, std::vector& umiCount, diff --git a/src/GZipWriter.cpp b/src/GZipWriter.cpp index 1719d8188..0b4e95376 100644 --- a/src/GZipWriter.cpp +++ b/src/GZipWriter.cpp @@ -1865,8 +1865,8 @@ bool GZipWriter::writeEquivCounts( const AlevinOpts& aopts, SCExpT& readExp); template -bool GZipWriter::writeEquivCounts( - const AlevinOpts& aopts, +bool GZipWriter::writeEquivCounts( + const AlevinOpts& aopts, SCExpT& readExp); template bool GZipWriter::writeEquivCounts( @@ -1907,7 +1907,7 @@ template bool GZipWriter::writeMetaAlevin(const AlevinOpts& opts, boost::filesystem::path aux_dir); template bool -GZipWriter::writeMetaAlevin(const AlevinOpts& opts, +GZipWriter::writeMetaAlevin(const AlevinOpts& opts, boost::filesystem::path aux_dir); template bool GZipWriter::writeMetaAlevin(const AlevinOpts& opts, diff --git a/src/ProgramOptionsGenerator.cpp b/src/ProgramOptionsGenerator.cpp index d3a4f22da..013aa17b6 100644 --- a/src/ProgramOptionsGenerator.cpp +++ b/src/ProgramOptionsGenerator.cpp @@ -335,8 +335,8 @@ namespace salmon { "alevin-developer Options"); alevindevs.add_options() ( - "indrop", po::bool_switch()->default_value(alevin::defaults::isInDrop), - "Use inDrop (not extensively tested) Single Cell protocol for the library. must specify w1 too.") + "indropV2", po::bool_switch()->default_value(alevin::defaults::isInDrop), + "Use inDropV2 Single Cell protocol for the library. Must specify w1 too.") ( "w1", po::value(), "Must be used in conjunction with inDrop;") diff --git a/src/SalmonAlevin.cpp b/src/SalmonAlevin.cpp index 855ead5a1..5222235db 100644 --- a/src/SalmonAlevin.cpp +++ b/src/SalmonAlevin.cpp @@ -3031,11 +3031,11 @@ int alevinQuant(AlevinOpts& aopt, size_t numLowConfidentBarcode); template -int alevin_sc_align(AlevinOpts& aopt, +int alevin_sc_align(AlevinOpts& aopt, SalmonOpts& sopt, boost::program_options::parsed_options& orderedOptions); template -int alevinQuant(AlevinOpts& aopt, +int alevinQuant(AlevinOpts& aopt, SalmonOpts& sopt, SoftMapT& barcodeMap, TrueBcsT& trueBarcodes, diff --git a/src/WhiteList.cpp b/src/WhiteList.cpp index cef7c9acf..2763c0b4b 100644 --- a/src/WhiteList.cpp +++ b/src/WhiteList.cpp @@ -260,7 +260,7 @@ namespace alevin { std::vector& trueBarcodes, bool useRibo, bool useMito, size_t numLowConfidentBarcode); - template bool performWhitelisting(AlevinOpts& aopt, + template bool performWhitelisting(AlevinOpts& aopt, std::vector& trueBarcodes, bool useRibo, bool useMito, size_t numLowConfidentBarcode); From 6f4e427d73399f855693ce141e1859b04824c25b Mon Sep 17 00:00:00 2001 From: Guillaume Marcais Date: Thu, 3 Jun 2021 06:54:10 +0200 Subject: [PATCH 10/23] Refactoring * argument parsing * allow early load of the index --- include/ReadExperiment.hpp | 31 +--- include/SalmonIndex.hpp | 5 + src/Alevin.cpp | 51 +++-- src/BuildSalmonIndex.cpp | 24 ++- src/Salmon.cpp | 128 ++++++------- src/SalmonAlevin.cpp | 310 ++++++++++++++----------------- src/SalmonQuantMerge.cpp | 3 +- src/SalmonQuantify.cpp | 12 +- src/SalmonQuantifyAlignments.cpp | 2 +- 9 files changed, 279 insertions(+), 287 deletions(-) diff --git a/include/ReadExperiment.hpp b/include/ReadExperiment.hpp index c84f923ec..40b2f7882 100644 --- a/include/ReadExperiment.hpp +++ b/include/ReadExperiment.hpp @@ -25,6 +25,7 @@ // Boost includes #include +#include #include // Cereal includes @@ -48,10 +49,12 @@ class ReadExperiment { public: ReadExperiment(std::vector& readLibraries, // const boost::filesystem::path& transcriptFile, - const boost::filesystem::path& indexDirectory, + SalmonIndex* salmonIndex, + // const boost::filesystem::path& indexDirectory, SalmonOpts& sopt) : readLibraries_(readLibraries), // transcriptFile_(transcriptFile), + salmonIndex_(salmonIndex), transcripts_(std::vector()), totalAssignedFragments_(0), fragStartDists_(5), posBiasFW_(5), posBiasRC_(5), posBiasExpectFW_(5), posBiasExpectRC_(5), /*seqBiasModel_(1.0),*/ eqBuilder_(sopt.jointLog, sopt.maxHashResizeThreads), @@ -115,24 +118,6 @@ class ReadExperiment { } */ - // ==== Figure out the index type - boost::filesystem::path versionPath = indexDirectory / "versionInfo.json"; - SalmonIndexVersionInfo versionInfo; - versionInfo.load(versionPath); - if (versionInfo.indexVersion() == 0) { - fmt::MemoryWriter infostr; - infostr << "Error: The index version file " << versionPath.string() - << " doesn't seem to exist. Please try re-building the salmon " - "index."; - throw std::invalid_argument(infostr.str()); - } - // Check index version compatibility here - auto indexType = versionInfo.indexType(); - // ==== Figure out the index type - - salmonIndex_.reset(new SalmonIndex(sopt.jointLog, indexType)); - salmonIndex_->load(indexDirectory); - // Now we'll have either an FMD-based index or a QUASI index // dispatch on the correct type. fmt::MemoryWriter infostr; @@ -159,7 +144,7 @@ class ReadExperiment { // Create the cluster forest for this set of transcripts clusters_.reset(new ClusterForest(transcripts_.size(), transcripts_)); } - + EQBuilderT& equivalenceClassBuilder() { return eqBuilder_; } std::string getIndexSeqHash256() const { return salmonIndex_->seqHash256(); } @@ -262,7 +247,7 @@ class ReadExperiment { } } - SalmonIndex* getIndex() { return salmonIndex_.get(); } + SalmonIndex* getIndex() { return salmonIndex_; } template void loadTranscriptsFromPuff(PuffIndexT* idx_, const SalmonOpts& sopt) { @@ -416,7 +401,7 @@ class ReadExperiment { std::atomic burnedIn{ totalAssignedFragments_ + numAssignedFragments_ >= sopt.numBurninFrags}; for (auto& rl : readLibraries_) { - processReadLibrary(rl, salmonIndex_.get(), transcripts_, clusterForest(), + processReadLibrary(rl, salmonIndex_, transcripts_, clusterForest(), *(fragLengthDist_.get()), numAssignedFragments_, numThreads, burnedIn); } @@ -806,7 +791,7 @@ class ReadExperiment { /** * The index we've built on the set of transcripts. */ - std::unique_ptr salmonIndex_{nullptr}; + SalmonIndex* salmonIndex_{nullptr}; /** * The cluster forest maintains the dynamic relationship * defined by transcripts and reads --- if two transcripts diff --git a/include/SalmonIndex.hpp b/include/SalmonIndex.hpp index 8bf38368c..5ef757553 100644 --- a/include/SalmonIndex.hpp +++ b/include/SalmonIndex.hpp @@ -246,4 +246,9 @@ class SalmonIndex { std::string decoyNameHash256_; }; +// Convenience function to load an index +std::unique_ptr +checkLoadIndex(const boost::filesystem::path& indexDirectory, + std::shared_ptr& logger); + #endif //__SALMON_INDEX_HPP diff --git a/src/Alevin.cpp b/src/Alevin.cpp index 9debe68fa..e4d2f020c 100644 --- a/src/Alevin.cpp +++ b/src/Alevin.cpp @@ -19,6 +19,7 @@
#include #include #include @@ -63,11 +64,11 @@ // salmon includes #include "FastxParser.hpp" +#include "ProgramOptionsGenerator.hpp" #include "SalmonConfig.hpp" #include "SalmonDefaults.hpp" #include "SalmonOpts.hpp" #include "SalmonUtils.hpp" -#include "ProgramOptionsGenerator.hpp" using paired_parser_qual = fastx_parser::FastxParser; using single_parser = fastx_parser::FastxParser; @@ -78,20 +79,18 @@ namespace apt = alevin::protocols; namespace aut = alevin::utils; template -int alevin_sc_align(AlevinOpts& aopt, - SalmonOpts& sopt, - boost::program_options::parsed_options& orderedOptions); +int alevin_sc_align(AlevinOpts& aopt, SalmonOpts& sopt, + boost::program_options::parsed_options& orderedOptions, + std::unique_ptr& salmonIndex); template -int alevinQuant(AlevinOpts& aopt, - SalmonOpts& sopt, - SoftMapT& barcodeMap, - TrueBcsT& trueBarcodes, +int alevinQuant(AlevinOpts& aopt, SalmonOpts& sopt, + SoftMapT& barcodeMap, TrueBcsT& trueBarcodes, spp::sparse_hash_map& txpToGeneMap, spp::sparse_hash_map& geneIdxMap, boost::program_options::parsed_options& orderedOptions, - CFreqMapT& freqCounter, - size_t numLowConfidentBarcode); + CFreqMapT& freqCounter, size_t numLowConfidentBarcode, + std::unique_ptr& salmonIndex); //colors for progress monitoring const char RESET_COLOR[] = "\x1b[0m"; @@ -835,7 +834,8 @@ void initiatePipeline(AlevinOpts& aopt, boost::program_options::variables_map& vm, std::string commentString, bool noTgMap, std::vector barcodeFiles, - std::vector readFiles){ + std::vector readFiles, + std::unique_ptr& salmonIndex){ bool isOptionsOk = aut::processAlevinOpts(aopt, sopt, noTgMap, vm); if (!isOptionsOk){ aopt.jointLog->flush(); @@ -900,8 +900,7 @@ void initiatePipeline(AlevinOpts& aopt, } // do the actual mapping - auto rc = alevin_sc_align(aopt, sopt, orderedOptions); - + auto rc = alevin_sc_align(aopt, sopt, orderedOptions, salmonIndex); if (rc == 0) { aopt.jointLog->info("sc-align successful."); } else { @@ -949,7 +948,7 @@ void initiatePipeline(AlevinOpts& aopt, aopt.jointLog->info("Done with Barcode Processing; Moving to Quantify\n"); alevinQuant(aopt, sopt, barcodeSoftMap, trueBarcodes, txpToGeneMap, geneIdxMap, orderedOptions, - freqCounter, numLowConfidentBarcode); + freqCounter, numLowConfidentBarcode, salmonIndex); } else{ boost::filesystem::path cmdInfoPath = vm["output"].as(); @@ -962,7 +961,7 @@ void initiatePipeline(AlevinOpts& aopt, } } -int salmonBarcoding(int argc, const char* argv[]) { +int salmonBarcoding(int argc, const char* argv[], std::unique_ptr& salmonIndex) { namespace bfs = boost::filesystem; namespace po = boost::program_options; @@ -1077,7 +1076,7 @@ salmon-based processing of single-cell RNA-seq data. //aopt.jointLog->warn("Using DropSeq Setting for Alevin"); initiatePipeline(aopt, sopt, orderedOptions, vm, commentString, noTgMap, - barcodeFiles, readFiles); + barcodeFiles, readFiles, salmonIndex); } else if(indrop){ std::cout<<"Indrop get neighbors removed, please use other protocols"; @@ -1089,7 +1088,7 @@ salmon-based processing of single-cell RNA-seq data. //aopt.jointLog->warn("Using InDrop Setting for Alevin"); initiatePipeline(aopt, sopt, orderedOptions, vm, commentString, noTgMap, - barcodeFiles, readFiles); + barcodeFiles, readFiles, salmonIndex); } else{ fmt::print(stderr, "ERROR: indrop needs w1 flag too.\n Exiting Now"); @@ -1105,7 +1104,7 @@ salmon-based processing of single-cell RNA-seq data. //aopt.jointLog->warn("Using InDrop Setting for Alevin"); initiatePipeline(aopt, sopt, orderedOptions, vm, commentString, noTgMap, - barcodeFiles, readFiles); + barcodeFiles, readFiles, salmonIndex); } else{ fmt::print(stderr, "ERROR: citeseq needs featureStart and featureLength flag too.\n Exiting Now"); @@ -1117,54 +1116,54 @@ salmon-based processing of single-cell RNA-seq data. //aopt.jointLog->warn("Using 10x v3 Setting for Alevin"); initiatePipeline(aopt, sopt, orderedOptions, vm, commentString, noTgMap, - barcodeFiles, readFiles); + barcodeFiles, readFiles, salmonIndex); } else if(chrom){ AlevinOpts aopt; //aopt.jointLog->warn("Using 10x v2 Setting for Alevin"); initiatePipeline(aopt, sopt, orderedOptions, vm, commentString, noTgMap, - barcodeFiles, readFiles); + barcodeFiles, readFiles, salmonIndex); } else if(gemcode){ AlevinOpts aopt; //aopt.jointLog->warn("Using 10x v1 Setting for Alevin"); initiatePipeline(aopt, sopt, orderedOptions, vm, commentString, noTgMap, - unmateFiles, readFiles); + unmateFiles, readFiles, salmonIndex); } else if(celseq){ AlevinOpts aopt; //aopt.jointLog->warn("Using CEL-Seq Setting for Alevin"); initiatePipeline(aopt, sopt, orderedOptions, vm, commentString, noTgMap, - barcodeFiles, readFiles); + barcodeFiles, readFiles, salmonIndex); } else if(celseq2){ AlevinOpts aopt; //aopt.jointLog->warn("Using CEL-Seq2 Setting for Alevin"); initiatePipeline(aopt, sopt, orderedOptions, vm, commentString, noTgMap, - barcodeFiles, readFiles); + barcodeFiles, readFiles, salmonIndex); } else if(quartzseq2){ AlevinOpts aopt; //aopt.jointLog->warn("Using Quartz-Seq2 Setting for Alevin"); initiatePipeline(aopt, sopt, orderedOptions, vm, commentString, noTgMap, - barcodeFiles, readFiles); + barcodeFiles, readFiles, salmonIndex); } else if (custom_old) { AlevinOpts aopt; //aopt.jointLog->warn("Using Custom Setting for Alevin"); initiatePipeline(aopt, sopt, orderedOptions, vm, commentString, noTgMap, - barcodeFiles, readFiles); + barcodeFiles, readFiles, salmonIndex); } else if (custom_new) { AlevinOpts aopt; //aopt.jointLog->warn("Using Custom Setting for Alevin"); initiatePipeline(aopt, sopt, orderedOptions, vm, commentString, noTgMap, - barcodeFiles, readFiles); + barcodeFiles, readFiles, salmonIndex); } } catch (po::error& e) { diff --git a/src/BuildSalmonIndex.cpp b/src/BuildSalmonIndex.cpp index 315feee3f..a9fc758fb 100644 --- a/src/BuildSalmonIndex.cpp +++ b/src/BuildSalmonIndex.cpp @@ -43,7 +43,7 @@ // http://stackoverflow.com/questions/108318/whats-the-simplest-way-to-test-whether-a-number-is-a-power-of-2-in-c bool isPowerOfTwo(uint32_t n) { return (n > 0 and (n & (n - 1)) == 0); } -int salmonIndex(int argc, const char* argv[]) { +int salmonIndex(int argc, const char* argv[], std::unique_ptr& /* salmonIndex */) { using std::string; namespace bfs = boost::filesystem; @@ -256,3 +256,25 @@ Creates a salmon index. } return ret; } + +std::unique_ptr checkLoadIndex(const boost::filesystem::path& indexDirectory, std::shared_ptr& logger) { + // ==== Figure out the index type + boost::filesystem::path versionPath = + indexDirectory / "versionInfo.json"; + SalmonIndexVersionInfo versionInfo; + versionInfo.load(versionPath); + if (versionInfo.indexVersion() == 0) { + fmt::MemoryWriter infostr; + infostr + << "Error: The index version file " << versionPath.string() + << " doesn't seem to exist. Please try re-building the salmon " + "index."; + throw std::invalid_argument(infostr.str()); + } + // Check index version compatibility here + auto indexType = versionInfo.indexType(); + // ==== Figure out the index type + std::unique_ptr res(new SalmonIndex(logger, indexType)); + res->load(indexDirectory); + return res; +} diff --git a/src/Salmon.cpp b/src/Salmon.cpp index b6e46d88d..bcb674d02 100644 --- a/src/Salmon.cpp +++ b/src/Salmon.cpp @@ -46,8 +46,9 @@ #include "GenomicFeature.hpp" #include "SalmonConfig.hpp" #include "VersionChecker.hpp" +#include "SalmonIndex.hpp" -int help(const std::vector& /*opts*/) { +int help(const std::vector& /*opts*/) { fmt::MemoryWriter helpMsg; helpMsg.write("salmon v{}\n\n", salmon::version); helpMsg.write( @@ -90,10 +91,12 @@ int dualModeMessage() { return 0; } +typedef std::function& index)> SubCmdType; + /** * Bonus! */ -int salmonSwim(int /*argc*/, const char* /*argv*/[]) { +int salmonSwim(int /*argc*/, const char* /*argv*/[], std::unique_ptr& /*index*/) { std::cout << R"( _____ __ @@ -144,17 +147,18 @@ Nature Methods. 2017;14(4):417-419. doi: 10.1038/nmeth.4197 )"; } -int salmonIndex(int argc, const char* argv[]); -int salmonQuantify(int argc, const char* argv[]); -int salmonAlignmentQuantify(int argc, const char* argv[]); +int salmonIndex(int argc, const char* argv[], std::unique_ptr& index); +int salmonQuantify(int argc, const char* argv[], std::unique_ptr& index); +int salmonAlignmentQuantify(int argc, const char* argv[], std::unique_ptr& index); +int salmonAlignmentDualMode(int argc, const char* argv[], std::unique_ptr& index); // TODO : PF_INTEGRATION -int salmonBarcoding(int argc, const char* argv[]); -int salmonQuantMerge(int argc, const char* argv[]); +int salmonBarcoding(int argc, const char* argv[], std::unique_ptr& index); +int salmonQuantMerge(int argc, const char* argv[], + std::unique_ptr& index); bool verbose = false; -int main(int argc, char* argv[]) { - show_backtrace(); +int main(int argc, const char* argv[]) { using std::string; namespace po = boost::program_options; std::setlocale(LC_ALL, "en_US.UTF-8"); @@ -235,9 +239,9 @@ int main(int argc, char* argv[]) { opts.insert(opts.begin(), "--help"); } - std::unordered_map> cmds( + std::unordered_map cmds( {{"index", salmonIndex}, - {"quant", salmonQuantify}, + {"quant", salmonAlignmentDualMode}, {"quantmerge", salmonQuantMerge}, // TODO : PF_INTEGRATION {"alevin", salmonBarcoding}, @@ -251,64 +255,24 @@ int main(int argc, char* argv[]) { std::copy_n( &argv[topLevelArgc], argc-topLevelArgc, &argv2[1] ); */ - int32_t subCommandArgc = opts.size() + 1; - std::unique_ptr argv2(new const char*[subCommandArgc]); + std::unique_ptr preloadedIndex; + + int32_t nargc = opts.size() + 1; + std::unique_ptr argv2(new const char*[nargc]); argv2[0] = argv[0]; - for (int32_t i = 0; i < subCommandArgc - 1; ++i) { + for (int32_t i = 0; i < nargc - 1; ++i) { argv2[i + 1] = opts[i].c_str(); } + const char** nargv = argv2.get(); - auto cmdMain = cmds.find(cmd); - if (cmdMain == cmds.end()) { - // help(subCommandArgc, argv2); - return help(opts); - } else { - // If the command is quant; determine whether - // we're quantifying with raw sequences or alignments - if (cmdMain->first == "quant") { - - if (subCommandArgc < 2) { - return dualModeMessage(); - } - // detect mode-specific help request - if (strncmp(argv2[1], "--help-alignment", 16) == 0) { - std::vector helpStr{'-', '-', 'h', 'e', 'l', 'p', '\0'}; - const char* helpArgv[] = {argv[0], &helpStr[0]}; - return salmonAlignmentQuantify(2, helpArgv); - } else if (strncmp(argv2[1], "--help-reads", 12) == 0) { - std::vector helpStr{'-', '-', 'h', 'e', 'l', 'p', '\0'}; - const char* helpArgv[] = {argv[0], &helpStr[0]}; - return salmonQuantify(2, helpArgv); - } - - // detect general help request - if (strncmp(argv2[1], "--help", 6) == 0 or - strncmp(argv2[1], "-h", 2) == 0) { - return dualModeMessage(); - } - - // otherwise, detect and dispatch the correct mode - bool useSalmonAlign{false}; - for (int32_t i = 0; i < subCommandArgc; ++i) { - if (strncmp(argv2[i], "-a", 2) == 0 or - strncmp(argv2[i], "-e", 2) == 0 or - strncmp(argv2[i], "--alignments", 12) == 0 or - strncmp(argv2[i], "--eqclasses", 11) == 0 or - strcmp(argv2[i], "--ont") == 0) { - useSalmonAlign = true; - break; - } - } - if (useSalmonAlign) { - return salmonAlignmentQuantify(subCommandArgc, argv2.get()); - } else { - return salmonQuantify(subCommandArgc, argv2.get()); - } - } else { - return cmdMain->second(subCommandArgc, argv2.get()); + while(true) { + auto cmdMain = cmds.find(cmd); + if (cmdMain == cmds.end()) { + // help(subCommandArgc, argv2); + return help(opts); } + return cmdMain->second(nargc, nargv, preloadedIndex); } - } catch (po::error& e) { std::cerr << "Program Option Error (main) : [" << e.what() << "].\n Exiting.\n"; @@ -321,3 +285,41 @@ int main(int argc, char* argv[]) { return 0; } + +int salmonAlignmentDualMode(int argc, const char* argv[], std::unique_ptr& index) { + // If the command is quant; determine whether + // we're quantifying with raw sequences or alignments + if (argc < 2) { + return dualModeMessage(); + } + // detect mode-specific help request + if (strncmp(argv[1], "--help-alignment", 16) == 0) { + const char* helpArgv[] = {argv[0], "--help", nullptr}; + return salmonAlignmentQuantify(2, helpArgv, index); + } else if (strncmp(argv[1], "--help-reads", 12) == 0) { + const char* helpArgv[] = {argv[0], "--help", nullptr}; + return salmonQuantify(2, helpArgv, index); + } + + // detect general help request + if (strncmp(argv[1], "--help", 6) == 0 or strncmp(argv[1], "-h", 2) == 0) { + return dualModeMessage(); + } + + // otherwise, detect and dispatch the correct mode + bool useSalmonAlign{false}; + for (int i = 0; i < argc; ++i) { + if (strncmp(argv[i], "-a", 2) == 0 or + strncmp(argv[i], "-e", 2) == 0 or + strncmp(argv[i], "--alignments", 12) == 0 or + strncmp(argv[i], "--eqclasses", 11) == 0) { + useSalmonAlign = true; + break; + } + } + if (useSalmonAlign) { + return salmonAlignmentQuantify(argc, argv, index); + } else { + return salmonQuantify(argc, argv, index); + } +} diff --git a/src/SalmonAlevin.cpp b/src/SalmonAlevin.cpp index 535876f10..6b4078968 100644 --- a/src/SalmonAlevin.cpp +++ b/src/SalmonAlevin.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -2662,7 +2663,8 @@ void alevinOptimize( std::vector& trueBarcodesVec, template int alevin_sc_align(AlevinOpts& aopt, SalmonOpts& sopt, - boost::program_options::parsed_options& orderedOptions){ + boost::program_options::parsed_options& orderedOptions, + std::unique_ptr& salmonIndex){ using std::cerr; using std::vector; using std::string; @@ -2689,13 +2691,12 @@ int alevin_sc_align(AlevinOpts& aopt, } // ==== END: Library format processing === - SalmonIndexVersionInfo versionInfo; - boost::filesystem::path versionPath = indexDirectory / "versionInfo.json"; - versionInfo.load(versionPath); - auto idxType = versionInfo.indexType(); + if(!salmonIndex) + salmonIndex = checkLoadIndex(indexDirectory, sopt.jointLog); + auto idxType = salmonIndex->indexType(); MappingStatistics mstats; - ReadExperimentT experiment(readLibraries, indexDirectory, sopt); + ReadExperimentT experiment(readLibraries, salmonIndex.get(), sopt); // We currently do not support decoy sequence in the // --justAlign or --sketch modes, so check that the @@ -2778,7 +2779,8 @@ int alevinQuant(AlevinOpts& aopt, spp::sparse_hash_map& txpToGeneMap, spp::sparse_hash_map& geneIdxMap, boost::program_options::parsed_options& orderedOptions, - CFreqMapT& freqCounter, size_t numLowConfidentBarcode){ + CFreqMapT& freqCounter, size_t numLowConfidentBarcode, + std::unique_ptr& salmonIndex){ using std::cerr; using std::vector; using std::string; @@ -2804,14 +2806,12 @@ int alevinQuant(AlevinOpts& aopt, std::exit(1); } // ==== END: Library format processing === - - SalmonIndexVersionInfo versionInfo; - boost::filesystem::path versionPath = indexDirectory / "versionInfo.json"; - versionInfo.load(versionPath); - auto idxType = versionInfo.indexType(); + if(!salmonIndex) + salmonIndex = checkLoadIndex(indexDirectory, sopt.jointLog); + auto idxType = salmonIndex->indexType(); MappingStatistics mstats; - ReadExperimentT experiment(readLibraries, indexDirectory, sopt); + ReadExperimentT experiment(readLibraries, salmonIndex.get(), sopt); //experiment.computePolyAPositions(); // This will be the class in charge of maintaining our @@ -2996,168 +2996,146 @@ int alevinQuant(AlevinOpts& aopt, namespace apt = alevin::protocols; -template -int alevin_sc_align(AlevinOpts& aopt, - SalmonOpts& sopt, - boost::program_options::parsed_options& orderedOptions); - -template -int alevinQuant(AlevinOpts& aopt, - SalmonOpts& sopt, - SoftMapT& barcodeMap, - TrueBcsT& trueBarcodes, - spp::sparse_hash_map& txpToGeneMap, - spp::sparse_hash_map& geneIdxMap, - boost::program_options::parsed_options& orderedOptions, - CFreqMapT& freqCounter, - size_t numLowConfidentBarcode); - -template -int alevin_sc_align(AlevinOpts& aopt, - SalmonOpts& sopt, - boost::program_options::parsed_options& orderedOptions); template -int alevinQuant(AlevinOpts& aopt, - SalmonOpts& sopt, - SoftMapT& barcodeMap, - TrueBcsT& trueBarcodes, - spp::sparse_hash_map& txpToGeneMap, - spp::sparse_hash_map& geneIdxMap, - boost::program_options::parsed_options& orderedOptions, - CFreqMapT& freqCounter, - size_t numLowConfidentBarcode); +int alevin_sc_align(AlevinOpts& aopt, SalmonOpts& sopt, + boost::program_options::parsed_options& orderedOptions, + std::unique_ptr& salmonIndex); + +template int +alevinQuant(AlevinOpts& aopt, SalmonOpts& sopt, + SoftMapT& barcodeMap, TrueBcsT& trueBarcodes, + spp::sparse_hash_map& txpToGeneMap, + spp::sparse_hash_map& geneIdxMap, + boost::program_options::parsed_options& orderedOptions, + CFreqMapT& freqCounter, size_t numLowConfidentBarcode, + std::unique_ptr& salmonIndex); -template -int alevin_sc_align(AlevinOpts& aopt, - SalmonOpts& sopt, - boost::program_options::parsed_options& orderedOptions); template -int alevinQuant(AlevinOpts& aopt, - SalmonOpts& sopt, - SoftMapT& barcodeMap, - TrueBcsT& trueBarcodes, - spp::sparse_hash_map& txpToGeneMap, - spp::sparse_hash_map& geneIdxMap, +int alevin_sc_align(AlevinOpts& aopt, SalmonOpts& sopt, + boost::program_options::parsed_options& orderedOptions, + std::unique_ptr& salmonIndex); +template int +alevinQuant(AlevinOpts& aopt, SalmonOpts& sopt, + SoftMapT& barcodeMap, TrueBcsT& trueBarcodes, + spp::sparse_hash_map& txpToGeneMap, + spp::sparse_hash_map& geneIdxMap, + boost::program_options::parsed_options& orderedOptions, + CFreqMapT& freqCounter, size_t numLowConfidentBarcode, + std::unique_ptr& salmonIndex); + +template int +alevin_sc_align(AlevinOpts& aopt, SalmonOpts& sopt, boost::program_options::parsed_options& orderedOptions, - CFreqMapT& freqCounter, - size_t numLowConfidentBarcode); - -template -int alevin_sc_align(AlevinOpts& aopt, - SalmonOpts& sopt, - boost::program_options::parsed_options& orderedOptions); -template -int alevinQuant(AlevinOpts& aopt, - SalmonOpts& sopt, - SoftMapT& barcodeMap, - TrueBcsT& trueBarcodes, - spp::sparse_hash_map& txpToGeneMap, - spp::sparse_hash_map& geneIdxMap, + std::unique_ptr& salmonIndex); +template int +alevinQuant(AlevinOpts& aopt, SalmonOpts& sopt, + SoftMapT& barcodeMap, TrueBcsT& trueBarcodes, + spp::sparse_hash_map& txpToGeneMap, + spp::sparse_hash_map& geneIdxMap, + boost::program_options::parsed_options& orderedOptions, + CFreqMapT& freqCounter, size_t numLowConfidentBarcode, + std::unique_ptr& salmonIndex); + +template int +alevin_sc_align(AlevinOpts& aopt, SalmonOpts& sopt, boost::program_options::parsed_options& orderedOptions, - CFreqMapT& freqCounter, - size_t numLowConfidentBarcode); - -template -int alevin_sc_align(AlevinOpts& aopt, - SalmonOpts& sopt, - boost::program_options::parsed_options& orderedOptions); -template -int alevinQuant(AlevinOpts& aopt, - SalmonOpts& sopt, - SoftMapT& barcodeMap, - TrueBcsT& trueBarcodes, - spp::sparse_hash_map& txpToGeneMap, - spp::sparse_hash_map& geneIdxMap, + std::unique_ptr& salmonIndex); +template int +alevinQuant(AlevinOpts& aopt, SalmonOpts& sopt, + SoftMapT& barcodeMap, TrueBcsT& trueBarcodes, + spp::sparse_hash_map& txpToGeneMap, + spp::sparse_hash_map& geneIdxMap, + boost::program_options::parsed_options& orderedOptions, + CFreqMapT& freqCounter, size_t numLowConfidentBarcode, + std::unique_ptr& salmonIndex); + +template int +alevin_sc_align(AlevinOpts& aopt, SalmonOpts& sopt, boost::program_options::parsed_options& orderedOptions, - CFreqMapT& freqCounter, - size_t numLowConfidentBarcode); - -template -int alevin_sc_align(AlevinOpts& aopt, - SalmonOpts& sopt, - boost::program_options::parsed_options& orderedOptions); -template -int alevinQuant(AlevinOpts& aopt, - SalmonOpts& sopt, - SoftMapT& barcodeMap, - TrueBcsT& trueBarcodes, - spp::sparse_hash_map& txpToGeneMap, - spp::sparse_hash_map& geneIdxMap, + std::unique_ptr& salmonIndex); +template int +alevinQuant(AlevinOpts& aopt, SalmonOpts& sopt, + SoftMapT& barcodeMap, TrueBcsT& trueBarcodes, + spp::sparse_hash_map& txpToGeneMap, + spp::sparse_hash_map& geneIdxMap, + boost::program_options::parsed_options& orderedOptions, + CFreqMapT& freqCounter, size_t numLowConfidentBarcode, + std::unique_ptr& salmonIndex); + +template int +alevin_sc_align(AlevinOpts& aopt, SalmonOpts& sopt, boost::program_options::parsed_options& orderedOptions, - CFreqMapT& freqCounter, - size_t numLowConfidentBarcode); - -template -int alevin_sc_align(AlevinOpts& aopt, - SalmonOpts& sopt, - boost::program_options::parsed_options& orderedOptions); -template -int alevinQuant(AlevinOpts& aopt, - SalmonOpts& sopt, - SoftMapT& barcodeMap, - TrueBcsT& trueBarcodes, - spp::sparse_hash_map& txpToGeneMap, - spp::sparse_hash_map& geneIdxMap, + std::unique_ptr& salmonIndex); +template int +alevinQuant(AlevinOpts& aopt, SalmonOpts& sopt, + SoftMapT& barcodeMap, TrueBcsT& trueBarcodes, + spp::sparse_hash_map& txpToGeneMap, + spp::sparse_hash_map& geneIdxMap, + boost::program_options::parsed_options& orderedOptions, + CFreqMapT& freqCounter, size_t numLowConfidentBarcode, + std::unique_ptr& salmonIndex); + +template int +alevin_sc_align(AlevinOpts& aopt, SalmonOpts& sopt, boost::program_options::parsed_options& orderedOptions, - CFreqMapT& freqCounter, - size_t numLowConfidentBarcode); - -template -int alevin_sc_align(AlevinOpts& aopt, - SalmonOpts& sopt, - boost::program_options::parsed_options& orderedOptions); -template -int alevinQuant(AlevinOpts& aopt, - SalmonOpts& sopt, - SoftMapT& barcodeMap, - TrueBcsT& trueBarcodes, - spp::sparse_hash_map& txpToGeneMap, - spp::sparse_hash_map& geneIdxMap, + std::unique_ptr& salmonIndex); +template int +alevinQuant(AlevinOpts& aopt, SalmonOpts& sopt, + SoftMapT& barcodeMap, TrueBcsT& trueBarcodes, + spp::sparse_hash_map& txpToGeneMap, + spp::sparse_hash_map& geneIdxMap, + boost::program_options::parsed_options& orderedOptions, + CFreqMapT& freqCounter, size_t numLowConfidentBarcode, + std::unique_ptr& salmonIndex); + +template int +alevin_sc_align(AlevinOpts& aopt, SalmonOpts& sopt, boost::program_options::parsed_options& orderedOptions, - CFreqMapT& freqCounter, - size_t numLowConfidentBarcode); - -template -int alevin_sc_align(AlevinOpts& aopt, - SalmonOpts& sopt, - boost::program_options::parsed_options& orderedOptions); -template -int alevinQuant(AlevinOpts& aopt, - SalmonOpts& sopt, - SoftMapT& barcodeMap, - TrueBcsT& trueBarcodes, - spp::sparse_hash_map& txpToGeneMap, - spp::sparse_hash_map& geneIdxMap, + std::unique_ptr& salmonIndex); +template int +alevinQuant(AlevinOpts& aopt, SalmonOpts& sopt, + SoftMapT& barcodeMap, TrueBcsT& trueBarcodes, + spp::sparse_hash_map& txpToGeneMap, + spp::sparse_hash_map& geneIdxMap, + boost::program_options::parsed_options& orderedOptions, + CFreqMapT& freqCounter, size_t numLowConfidentBarcode, + std::unique_ptr& salmonIndex); + +template int +alevin_sc_align(AlevinOpts& aopt, SalmonOpts& sopt, boost::program_options::parsed_options& orderedOptions, - CFreqMapT& freqCounter, - size_t numLowConfidentBarcode); - -template -int alevin_sc_align(AlevinOpts& aopt, - SalmonOpts& sopt, - boost::program_options::parsed_options& orderedOptions); -template -int alevin_sc_align(AlevinOpts& aopt, - SalmonOpts& sopt, - boost::program_options::parsed_options& orderedOptions); - -template -int alevinQuant(AlevinOpts& aopt, - SalmonOpts& sopt, - SoftMapT& barcodeMap, - TrueBcsT& trueBarcodes, - spp::sparse_hash_map& txpToGeneMap, - spp::sparse_hash_map& geneIdxMap, + std::unique_ptr& salmonIndex); +template int +alevinQuant(AlevinOpts& aopt, SalmonOpts& sopt, + SoftMapT& barcodeMap, TrueBcsT& trueBarcodes, + spp::sparse_hash_map& txpToGeneMap, + spp::sparse_hash_map& geneIdxMap, + boost::program_options::parsed_options& orderedOptions, + CFreqMapT& freqCounter, size_t numLowConfidentBarcode, + std::unique_ptr& salmonIndex); + +template int +alevin_sc_align(AlevinOpts& aopt, SalmonOpts& sopt, boost::program_options::parsed_options& orderedOptions, - CFreqMapT& freqCounter, - size_t numLowConfidentBarcode); -template -int alevinQuant(AlevinOpts& aopt, - SalmonOpts& sopt, - SoftMapT& barcodeMap, - TrueBcsT& trueBarcodes, - spp::sparse_hash_map& txpToGeneMap, - spp::sparse_hash_map& geneIdxMap, + std::unique_ptr& salmonIndex); +template int +alevin_sc_align(AlevinOpts& aopt, SalmonOpts& sopt, boost::program_options::parsed_options& orderedOptions, - CFreqMapT& freqCounter, - size_t numLowConfidentBarcode); + std::unique_ptr& salmonIndex); + +template int +alevinQuant(AlevinOpts& aopt, SalmonOpts& sopt, + SoftMapT& barcodeMap, TrueBcsT& trueBarcodes, + spp::sparse_hash_map& txpToGeneMap, + spp::sparse_hash_map& geneIdxMap, + boost::program_options::parsed_options& orderedOptions, + CFreqMapT& freqCounter, size_t numLowConfidentBarcode, + std::unique_ptr& salmonIndex); +template int +alevinQuant(AlevinOpts& aopt, SalmonOpts& sopt, + SoftMapT& barcodeMap, TrueBcsT& trueBarcodes, + spp::sparse_hash_map& txpToGeneMap, + spp::sparse_hash_map& geneIdxMap, + boost::program_options::parsed_options& orderedOptions, + CFreqMapT& freqCounter, size_t numLowConfidentBarcode, + std::unique_ptr& salmonIndex); diff --git a/src/SalmonQuantMerge.cpp b/src/SalmonQuantMerge.cpp index 4178b35f0..fc563cfe1 100644 --- a/src/SalmonQuantMerge.cpp +++ b/src/SalmonQuantMerge.cpp @@ -27,6 +27,7 @@ // C++ string formatting library #include "spdlog/fmt/fmt.h" // logger includes #include "spdlog/spdlog.h" +#include "SalmonIndex.hpp" enum class TargetColumn { LEN, ELEN, TPM, NREADS }; @@ -213,7 +214,7 @@ bool doMerge(QuantMergeOptions& qmOpts) { return true; } -int salmonQuantMerge(int argc, const char* argv[]) { +int salmonQuantMerge(int argc, const char* argv[], std::unique_ptr& /* salmonIndex */) { using std::cerr; using std::vector; using std::string; diff --git a/src/SalmonQuantify.cpp b/src/SalmonQuantify.cpp index cacc459aa..be7adaa6f 100644 --- a/src/SalmonQuantify.cpp +++ b/src/SalmonQuantify.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -2385,7 +2386,7 @@ void quantifyLibrary(ReadExperimentT& experiment, jointLog->info("finished quantifyLibrary()"); } -int salmonQuantify(int argc, const char* argv[]) { +int salmonQuantify(int argc, const char* argv[], std::unique_ptr& salmonIndex) { using std::cerr; using std::vector; using std::string; @@ -2489,13 +2490,12 @@ transcript abundance from RNA-seq reads } // ==== END: Library format processing === - SalmonIndexVersionInfo versionInfo; - boost::filesystem::path versionPath = indexDirectory / "versionInfo.json"; - versionInfo.load(versionPath); - auto idxType = versionInfo.indexType(); + if(!salmonIndex) { + salmonIndex = checkLoadIndex(indexDirectory, sopt.jointLog); + } MappingStatistics mstats; - ReadExperimentT experiment(readLibraries, indexDirectory, sopt); + ReadExperimentT experiment(readLibraries, salmonIndex.get(), sopt); // This will be the class in charge of maintaining our // rich equivalence classes diff --git a/src/SalmonQuantifyAlignments.cpp b/src/SalmonQuantifyAlignments.cpp index aad99c824..747d1ee35 100644 --- a/src/SalmonQuantifyAlignments.cpp +++ b/src/SalmonQuantifyAlignments.cpp @@ -1573,7 +1573,7 @@ bool runSingleEndSample(std::vector& alignmentFiles, bfs::path& trans return processSample(alnLib, requiredObservations, sopt, sopt.outputDirectory); } -int salmonAlignmentQuantify(int argc, const char* argv[]) { +int salmonAlignmentQuantify(int argc, const char* argv[], std::unique_ptr& /* salmon_index */) { using std::cerr; using std::vector; using std::string; From 373ff32fb55ab1851d80132a914198df4cbfb2b6 Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Thu, 16 Sep 2021 13:11:31 -0400 Subject: [PATCH 11/23] Update Alevin.cpp spacing -- re-trigger CI --- src/Alevin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Alevin.cpp b/src/Alevin.cpp index e4d2f020c..8f58db16a 100644 --- a/src/Alevin.cpp +++ b/src/Alevin.cpp @@ -894,6 +894,7 @@ void initiatePipeline(AlevinOpts& aopt, // write out the cmd_info.json to make sure we have that boost::filesystem::path outputDirectory = vm["output"].as(); bool isWriteOk = aut::writeCmdInfo(outputDirectory / "cmd_info.json", orderedOptions); + if(!isWriteOk){ fmt::print(stderr, "Writing cmd_info.json in output directory failed.\nExiting now."); exit(1); From 91129761d57c2b64fd1cd485fcc75f4963a0666b Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Mon, 27 Sep 2021 17:20:32 -0400 Subject: [PATCH 12/23] Update AlevinUtils.hpp Remove extra ":" from `salmon_version` in `cmd_info.json` --- include/AlevinUtils.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/AlevinUtils.hpp b/include/AlevinUtils.hpp index c22bf0c1a..65234f6a3 100644 --- a/include/AlevinUtils.hpp +++ b/include/AlevinUtils.hpp @@ -97,7 +97,7 @@ namespace alevin{ OrderedOptionsT& orderedOptions) { std::ofstream os(cmdInfoPath.string()); cereal::JSONOutputArchive oa(os); - oa(cereal::make_nvp("salmon_version:", std::string(salmon::version))); + oa(cereal::make_nvp("salmon_version", std::string(salmon::version))); for (auto& opt : orderedOptions.options) { if (opt.value.size() == 1) { oa(cereal::make_nvp(opt.string_key, opt.value.front())); From 30cb712877104cff6964138340e86106f6785d72 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 29 Oct 2021 12:52:32 -0400 Subject: [PATCH 13/23] revert change in CELSeq umi extraction --- src/AlevinUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AlevinUtils.cpp b/src/AlevinUtils.cpp index 7fa90c4ad..a4d074786 100644 --- a/src/AlevinUtils.cpp +++ b/src/AlevinUtils.cpp @@ -247,7 +247,7 @@ namespace alevin { std::string& umi){ (void)read2; return (read.length() >= pt.umiLength) ? - (umi.assign(read, pt.barcodeLength, pt.umiLength), true) : false; + (umi.assign(read, 0, pt.umiLength), true) : false; return true; } template <> From 2d03cdd94411f748d48f72b5db851cb8d9b5d2ca Mon Sep 17 00:00:00 2001 From: Gaurav Date: Wed, 3 Nov 2021 14:35:45 -0400 Subject: [PATCH 14/23] move localProtocol outside for loop --- src/SalmonAlevin.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SalmonAlevin.cpp b/src/SalmonAlevin.cpp index 029bebaa8..21ce43af7 100644 --- a/src/SalmonAlevin.cpp +++ b/src/SalmonAlevin.cpp @@ -634,6 +634,7 @@ void process_reads_sc_sketch(paired_parser* parser, ReadExperimentT& readExp, Re extraBAMtags.reserve(reserveSize); } + auto localProtocol = alevinOpts.protocol; for (size_t i = 0; i < rangeSize; ++i) { // For all the read in this batch auto& rp = rg[i]; readLenLeft = rp.first.seq.length(); @@ -672,7 +673,6 @@ void process_reads_sc_sketch(paired_parser* parser, ReadExperimentT& readExp, Re if (alevinOpts.protocol.end == bcEnd::FIVE || alevinOpts.protocol.end == bcEnd::THREE){ - auto localProtocol = alevinOpts.protocol; bool extracted_bc = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); seqOk = (extracted_bc) ? aut::sequenceCheck(barcode, Sequence::BARCODE) : false; @@ -1163,6 +1163,7 @@ void process_reads_sc_align(paired_parser* parser, ReadExperimentT& readExp, Rea extraBAMtags.reserve(reserveSize); } + auto localProtocol = alevinOpts.protocol; for (size_t i = 0; i < rangeSize; ++i) { // For all the read in this batch auto& rp = rg[i]; readLenLeft = rp.first.seq.length(); @@ -1193,7 +1194,6 @@ void process_reads_sc_align(paired_parser* parser, ReadExperimentT& readExp, Rea if (alevinOpts.protocol.end == bcEnd::FIVE || alevinOpts.protocol.end == bcEnd::THREE){ - auto localProtocol = alevinOpts.protocol; bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); seqOk = (extracted_barcode) ? aut::sequenceCheck(barcode, Sequence::BARCODE) : false; @@ -1620,6 +1620,7 @@ void processReadsQuasi( extraBAMtags.reserve(reserveSize); } + auto localProtocol = alevinOpts.protocol; for (size_t i = 0; i < rangeSize; ++i) { // For all the read in this batch auto& rp = rg[i]; readLenLeft = rp.first.seq.length(); @@ -1651,7 +1652,6 @@ void processReadsQuasi( if (alevinOpts.protocol.end == bcEnd::FIVE || alevinOpts.protocol.end == bcEnd::THREE){ - auto localProtocol = alevinOpts.protocol; bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); seqOk = (extracted_barcode) ? aut::sequenceCheck(barcode, Sequence::BARCODE) : false; From f104e7afea11aa5b31a98ebeb37af0b899dc0f35 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Wed, 3 Nov 2021 16:10:34 -0400 Subject: [PATCH 15/23] avoid accidental cb clash - add A to 20 bp cb and AC to 19 bp cb --- include/SingleCellProtocols.hpp | 2 +- src/AlevinUtils.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/SingleCellProtocols.hpp b/include/SingleCellProtocols.hpp index 43fe153e3..b4608d8e4 100644 --- a/include/SingleCellProtocols.hpp +++ b/include/SingleCellProtocols.hpp @@ -180,7 +180,7 @@ namespace alevin{ Custom() : Rule(0,0,BarcodeEnd::FIVE,0){} }; struct SciSeq3 : Rule{ - SciSeq3() : Rule(20, 8, BarcodeEnd::FIVE, 1073741824){} + SciSeq3() : Rule(21, 8, BarcodeEnd::FIVE, 1073741824){} std::string anchorSeq = "CAGAGC"; std::size_t anchorSeqLen = anchorSeq.length(); std::size_t anchorPos = 0; diff --git a/src/AlevinUtils.cpp b/src/AlevinUtils.cpp index a4d074786..4a26fe8f8 100644 --- a/src/AlevinUtils.cpp +++ b/src/AlevinUtils.cpp @@ -317,8 +317,9 @@ namespace alevin { && read.length() >= pt.barcodeLength + pt.umiLength + pt.anchorSeqLen) { std::string bcAssign = read.substr(0,pt.anchorPos) + read.substr(pt.anchorPos + pt.anchorSeqLen + pt.umiLength, pt.rtIdxLen); if (pt.anchorPos < pt.maxHairpinIndexLen) { // hairpin index can be 9 or 10 bp - bc = bc.substr(1,bc.length()); - bcAssign += "A"; + bcAssign += "AC"; + } else { + bcAssign += "A"; } bc.assign(bcAssign); return true; From 622cfa23c71b732a3adb767904b8642cf88cfa2c Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Wed, 3 Nov 2021 22:26:48 -0400 Subject: [PATCH 16/23] Update SalmonAlevin.cpp Bring `UMIBarcodeT` back into line with what is in develop. --- src/SalmonAlevin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SalmonAlevin.cpp b/src/SalmonAlevin.cpp index 21ce43af7..f08d72c71 100644 --- a/src/SalmonAlevin.cpp +++ b/src/SalmonAlevin.cpp @@ -159,7 +159,7 @@ namespace alevin{ // < std::numeric_limits::max() distinct barcodes / reads. // However, that assumption should be tested more thoroughly. using CellBarcodeT = uint32_t; - using UMIBarcodeT = uint32_t; + using UMIBarcodeT = uint64_t; template using AlevinAlnGroup = AlignmentGroup; template using AlnGroupVec = std::vector>; From 5b221927710fd43bbad4dcf92497924a7011a2ce Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 19 Nov 2021 15:56:13 -0500 Subject: [PATCH 17/23] add info and bc2len --- include/SingleCellProtocols.hpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/SingleCellProtocols.hpp b/include/SingleCellProtocols.hpp index 72836560c..6fd392a01 100644 --- a/include/SingleCellProtocols.hpp +++ b/include/SingleCellProtocols.hpp @@ -126,13 +126,12 @@ namespace alevin{ struct InDropV2 : Rule{ //InDropV2 starts from 5end with variable - //length barcodes that varies from 8 to 11 bp - // so provide the full length of the barcode - // UMI length is 6 - InDropV2(): Rule(19, 6, BarcodeEnd::FIVE, 22347776){} + //length barcodes where barcode1 varies from 8 to 11 bp + // followed by w1 sequence, 8 bp barcode2 and 6bp UMI + InDropV2(): Rule(20, 6, BarcodeEnd::FIVE, 22347776){} std::string w1; - std::size_t w1Length, maxHammingDist = 2; + std::size_t w1Length, maxHammingDist = 2, bc2Len = 8; void setW1(std::string& w1_){ w1 = w1_; w1Length = w1.length(); From 5915e3bcdd16e254fef65530f029df542498b197 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 19 Nov 2021 16:18:18 -0500 Subject: [PATCH 18/23] avoid barcode collision with padding --- src/AlevinUtils.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/AlevinUtils.cpp b/src/AlevinUtils.cpp index 06bb4b630..0ef2c06ea 100644 --- a/src/AlevinUtils.cpp +++ b/src/AlevinUtils.cpp @@ -238,7 +238,7 @@ namespace alevin { apt::InDropV2& pt, std::string& umi){ (void)read; - return (read2.length() >= pt.umiLength) ? + return (read2.length() >= pt.w1Length + pt.barcodeLength + pt.umiLength) ? (umi.assign(read2, pt.bc2EndPos, pt.umiLength), true) : false; return true; } @@ -356,14 +356,28 @@ namespace alevin { } if (!found) {return false;} } - bc = read2.substr(0, pt.w1Pos); - if(bc.size()<8 or bc.size()>11){ + if(pt.w1Pos < 8 or pt.w1Pos > 11){ return false; } + bc = read2.substr(0, pt.w1Pos); uint32_t offset = bc.size()+pt.w1.size(); - bc += read2.substr(offset, 8); - bc += std::string(pt.barcodeLength - bc.size(), 'A'); - pt.bc2EndPos = offset+8; + bc += read2.substr(offset, pt.bc2Len); + switch (pt.barcodeLength - bc.size()) + { + case 1: + bc += "A"; + break; + case 2: + bc += "AT"; + break; + case 3: + bc += "AAG"; + break; + case 4: + bc += "AAAC"; + break; + } + pt.bc2EndPos = offset+pt.bc2Len; return true; } else { return false; From fdddb9f4adbd8deb543fe7bb82adcf251f1d1a5e Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 19 Nov 2021 18:35:31 -0500 Subject: [PATCH 19/23] recover barcode only if extract barcode is true --- src/SalmonAlevin.cpp | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/SalmonAlevin.cpp b/src/SalmonAlevin.cpp index 5222235db..c88ac3e48 100644 --- a/src/SalmonAlevin.cpp +++ b/src/SalmonAlevin.cpp @@ -661,7 +661,7 @@ void process_reads_sc_sketch(paired_parser* parser, ReadExperimentT& readExp, Re //barcode.clear(); nonstd::optional barcodeIdx; extraBAMtags.clear(); - bool seqOk; + bool seqOk = false; // keep track of the *least* freqeuntly // occurring hit in this fragment to consider @@ -673,12 +673,12 @@ void process_reads_sc_sketch(paired_parser* parser, ReadExperimentT& readExp, Re alevinOpts.protocol.end == bcEnd::THREE){ auto localProtocol = alevinOpts.protocol; bool extracted_bc = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); - seqOk = (extracted_bc) ? - aut::sequenceCheck(barcode, Sequence::BARCODE) : false; - - if (not seqOk){ - bool recovered = aut::recoverBarcode(barcode); - if (recovered) { seqOk = true; } + if (extracted_barcode) { + seqOk = aut::sequenceCheck(barcode, Sequence::BARCODE); + if (not seqOk){ + bool recovered = aut::recoverBarcode(barcode); + if (recovered) { seqOk = true; } + } } // If we have a valid barcode @@ -1189,18 +1189,18 @@ void process_reads_sc_align(paired_parser* parser, ReadExperimentT& readExp, Rea //barcode.clear(); nonstd::optional barcodeIdx; extraBAMtags.clear(); - bool seqOk; + bool seqOk = false; if (alevinOpts.protocol.end == bcEnd::FIVE || alevinOpts.protocol.end == bcEnd::THREE){ auto localProtocol = alevinOpts.protocol; bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); - seqOk = (extracted_barcode) ? - aut::sequenceCheck(barcode, Sequence::BARCODE) : false; - - if (not seqOk){ - bool recovered = aut::recoverBarcode(barcode); - if (recovered) { seqOk = true; } + if (extracted_barcode) { + seqOk = aut::sequenceCheck(barcode, Sequence::BARCODE); + if (not seqOk){ + bool recovered = aut::recoverBarcode(barcode); + if (recovered) { seqOk = true; } + } } // If we have a valid barcode @@ -1648,18 +1648,18 @@ void processReadsQuasi( //barcode.clear(); nonstd::optional barcodeIdx; extraBAMtags.clear(); - bool seqOk; + bool seqOk = false; if (alevinOpts.protocol.end == bcEnd::FIVE || alevinOpts.protocol.end == bcEnd::THREE){ auto localProtocol = alevinOpts.protocol; bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); - seqOk = (extracted_barcode) ? - aut::sequenceCheck(barcode, Sequence::BARCODE) : false; - - if (not seqOk){ - bool recovered = aut::recoverBarcode(barcode); - if (recovered) { seqOk = true; } + if (extracted_barcode) { + seqOk = aut::sequenceCheck(barcode, Sequence::BARCODE); + if (not seqOk){ + bool recovered = aut::recoverBarcode(barcode); + if (recovered) { seqOk = true; } + } } // If we have a barcode sequence, but not yet an index From 2c3c01074d7cb5a055b3167715bef3746434716b Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 19 Nov 2021 18:42:31 -0500 Subject: [PATCH 20/23] fix typo --- src/SalmonAlevin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SalmonAlevin.cpp b/src/SalmonAlevin.cpp index c88ac3e48..788a6f2ea 100644 --- a/src/SalmonAlevin.cpp +++ b/src/SalmonAlevin.cpp @@ -672,7 +672,7 @@ void process_reads_sc_sketch(paired_parser* parser, ReadExperimentT& readExp, Re if (alevinOpts.protocol.end == bcEnd::FIVE || alevinOpts.protocol.end == bcEnd::THREE){ auto localProtocol = alevinOpts.protocol; - bool extracted_bc = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); + bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); if (extracted_barcode) { seqOk = aut::sequenceCheck(barcode, Sequence::BARCODE); if (not seqOk){ From 6829e44ffd930709b19f89771a5d775b2d6de099 Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Sat, 20 Nov 2021 22:04:39 -0500 Subject: [PATCH 21/23] get rid of redundant if --- src/SalmonAlevin.cpp | 48 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/src/SalmonAlevin.cpp b/src/SalmonAlevin.cpp index c087f50b4..52c27fffb 100644 --- a/src/SalmonAlevin.cpp +++ b/src/SalmonAlevin.cpp @@ -673,12 +673,24 @@ void process_reads_sc_sketch(paired_parser* parser, ReadExperimentT& readExp, Re if (alevinOpts.protocol.end == bcEnd::FIVE || alevinOpts.protocol.end == bcEnd::THREE){ + // If the barcode sequence could be extracted, then this is set to true, + // but the barcode sequence itself may still be invalid (e.g. contain `N` characters). + // However, if extracted_barcode is false here, there is no hope to even recover the + // barcode and we shouldn't attempt it. bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); + // If we could pull out something where the barcode sequence should have been + // then continue to process it. if (extracted_barcode) { + // if the barcode consisted of valid nucleotides, then seqOk is true + // otherwise false seqOk = aut::sequenceCheck(barcode, Sequence::BARCODE); if (not seqOk){ - bool recovered = aut::recoverBarcode(barcode); - if (recovered) { seqOk = true; } + // If the barcode contained invalid nucleotides + // this attempts to replace the first one with an `A`. + // If this returns true, there was only one `N` and we + // replaced it; otherwise there was more than one `N` + // and the barcode sequence should be treated as invalid. + seqOk = aut::recoverBarcode(barcode); } } @@ -1194,12 +1206,24 @@ void process_reads_sc_align(paired_parser* parser, ReadExperimentT& readExp, Rea if (alevinOpts.protocol.end == bcEnd::FIVE || alevinOpts.protocol.end == bcEnd::THREE){ + // If the barcode sequence could be extracted, then this is set to true, + // but the barcode sequence itself may still be invalid (e.g. contain `N` characters). + // However, if extracted_barcode is false here, there is no hope to even recover the + // barcode and we shouldn't attempt it. bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); + // If we could pull out something where the barcode sequence should have been + // then continue to process it. if (extracted_barcode) { + // if the barcode consisted of valid nucleotides, then seqOk is true + // otherwise false seqOk = aut::sequenceCheck(barcode, Sequence::BARCODE); if (not seqOk){ - bool recovered = aut::recoverBarcode(barcode); - if (recovered) { seqOk = true; } + // If the barcode contained invalid nucleotides + // this attempts to replace the first one with an `A`. + // If this returns true, there was only one `N` and we + // replaced it; otherwise there was more than one `N` + // and the barcode sequence should be treated as invalid. + seqOk = aut::recoverBarcode(barcode); } } @@ -1652,12 +1676,24 @@ void processReadsQuasi( if (alevinOpts.protocol.end == bcEnd::FIVE || alevinOpts.protocol.end == bcEnd::THREE){ + // If the barcode sequence could be extracted, then this is set to true, + // but the barcode sequence itself may still be invalid (e.g. contain `N` characters). + // However, if extracted_barcode is false here, there is no hope to even recover the + // barcode and we shouldn't attempt it. bool extracted_barcode = aut::extractBarcode(rp.first.seq, rp.second.seq, localProtocol, barcode); + // If we could pull out something where the barcode sequence should have been + // then continue to process it. if (extracted_barcode) { + // if the barcode consisted of valid nucleotides, then seqOk is true + // otherwise false seqOk = aut::sequenceCheck(barcode, Sequence::BARCODE); if (not seqOk){ - bool recovered = aut::recoverBarcode(barcode); - if (recovered) { seqOk = true; } + // If the barcode contained invalid nucleotides + // this attempts to replace the first one with an `A`. + // If this returns true, there was only one `N` and we + // replaced it; otherwise there was more than one `N` + // and the barcode sequence should be treated as invalid. + seqOk = aut::recoverBarcode(barcode); } } From 9fdee40f2f765d2b2c3799e3a4b062d396555348 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Mon, 22 Nov 2021 14:23:57 -0500 Subject: [PATCH 22/23] update single-cell protocol documentation --- doc/source/alevin.rst | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/doc/source/alevin.rst b/doc/source/alevin.rst index 49fc32d34..92449a215 100644 --- a/doc/source/alevin.rst +++ b/doc/source/alevin.rst @@ -1,10 +1,14 @@ Alevin ================ -Alevin is a tool --- integrated with the salmon software --- that introduces a family of algorithms for quantification and analysis of 3' tagged-end single-cell sequencing data. Currently alevin supports the following two major droplet based single-cell protocols: +Alevin is a tool --- integrated with the salmon software --- that introduces a family of algorithms for quantification and analysis of 3' tagged-end single-cell sequencing data. Currently alevin supports the following single-cell protocols: 1. Drop-seq 2. 10x-Chromium v1/2/3 +3. inDropV2 +4. CELSeq 1/2 +5. Quartz-Seq2 +6. sci-RNA-seq3 Alevin works under the same indexing scheme (as salmon) for the reference, and consumes the set of FASTA/Q files(s) containing the Cellular Barcode(CB) + Unique Molecule identifier (UMI) in one read file and the read sequence in the other. Given just the transcriptome and the raw read files, alevin generates a cell-by-gene count matrix (in a fraction of the time compared to other tools). @@ -177,6 +181,18 @@ map end-to-end. Instead, the score of the mapping will be the position along th highest score. This is the score which must reach the fraction threshold for the read to be considered as valid. +Single-cell protocol specific notes +------------------------------------ + +In cases where single-cell protocol supports variable length cellbarcodes, alevin adds nucleotide padding to make the lengths uniform. +Furthermore, the padding scheme ensures that there are no collisions added in the process. The padding scheme is as follows: + +1. sci-RNA-seq3: The barcode is composed of 9-10 bp hairpin adaptor and 10 bp reverse transcription index making it 19-20 bp long. If +the bacode is 20 bp long, alevin adds `A` and it adds `AC` if it is 19 bp long. Thus, the length of barcode in the output is 21 bp. +2. inDropV2: 8-11 bp barcode1 along with 8 bp barcode2 makes up the barcode. For barcode lengths of 16, 17, 18, and 19 bp, alevin adds +`AAAC`, `AAG`, `AT`, and `A` respectively. Thus, the length of barcode in the output is 20 bp. Furthermore, the position of barcode1 is +dependent on finding exact match of sequence `w1`. If exact match is not found, a search for `w1` is performed allowing a maximum hamming + distance 2 b/w `w1` and read2 substring of w1 length within the required bounds; the first match is returned. Output ------ From b7a216781599f8e63f9cada8a61d7b39b370948a Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Mon, 22 Nov 2021 17:03:34 -0500 Subject: [PATCH 23/23] update prepare for release --- current_version.txt | 4 +- doc/source/conf.py | 6 +- docker/Dockerfile | 2 +- docker/build_test.sh | 2 +- include/SalmonConfig.hpp | 6 +- include/cuckoohash_map.hh | 8 +- include/json.hpp | 14822 ++++++++++++++++++++++------------- scripts/fetchPufferfish.sh | 4 +- 8 files changed, 9366 insertions(+), 5488 deletions(-) diff --git a/current_version.txt b/current_version.txt index 4a74b730d..be8fab66b 100644 --- a/current_version.txt +++ b/current_version.txt @@ -1,3 +1,3 @@ VERSION_MAJOR 1 -VERSION_MINOR 5 -VERSION_PATCH 2 +VERSION_MINOR 6 +VERSION_PATCH 0 diff --git a/doc/source/conf.py b/doc/source/conf.py index 362952326..6f0a41f12 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -48,16 +48,16 @@ # General information about the project. project = u'Salmon' -copyright = u'2013-2017, Rob Patro, Geet Duggal, Mike Love, Rafael Irizarry and Carl Kingsford' +copyright = u'2013-2021, Rob Patro, Geet Duggal, Mike Love, Rafael Irizarry and Carl Kingsford' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '1.5' +version = '1.6' # The full version, including alpha/beta/rc tags. -release = '1.5.2' +release = '1.6.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docker/Dockerfile b/docker/Dockerfile index 11d62350c..3715a9163 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -6,7 +6,7 @@ MAINTAINER salmon.maintainer@gmail.com ENV PACKAGES git gcc make g++ libboost-all-dev liblzma-dev libbz2-dev \ ca-certificates zlib1g-dev libcurl4-openssl-dev curl unzip autoconf apt-transport-https ca-certificates gnupg software-properties-common wget -ENV SALMON_VERSION 1.5.2 +ENV SALMON_VERSION 1.6.0 # salmon binary will be installed in /home/salmon/bin/salmon diff --git a/docker/build_test.sh b/docker/build_test.sh index 1690b2c68..09ae6af7c 100644 --- a/docker/build_test.sh +++ b/docker/build_test.sh @@ -1,3 +1,3 @@ #! /bin/bash -SALMON_VERSION=1.5.2 +SALMON_VERSION=1.6.0 docker build --no-cache -t combinelab/salmon:${SALMON_VERSION} -t combinelab/salmon:latest . diff --git a/include/SalmonConfig.hpp b/include/SalmonConfig.hpp index 695983a01..f50fb8a5b 100644 --- a/include/SalmonConfig.hpp +++ b/include/SalmonConfig.hpp @@ -26,9 +26,9 @@ namespace salmon { constexpr char majorVersion[] = "1"; -constexpr char minorVersion[] = "5"; -constexpr char patchVersion[] = "2"; -constexpr char version[] = "1.5.2"; +constexpr char minorVersion[] = "6"; +constexpr char patchVersion[] = "0"; +constexpr char version[] = "1.6.0"; constexpr uint32_t indexVersion = 5; constexpr char requiredQuasiIndexVersion[] = "p7"; } // namespace salmon diff --git a/include/cuckoohash_map.hh b/include/cuckoohash_map.hh index a1824a61d..f91989106 100644 --- a/include/cuckoohash_map.hh +++ b/include/cuckoohash_map.hh @@ -113,7 +113,7 @@ public: maximum_hashpower_(NO_MAXIMUM_HASHPOWER), max_num_worker_threads_(0) { all_locks_.emplace_back(std::min(bucket_count(), size_type(kMaxNumLocks)), - spinlock(), get_allocator()); + get_allocator()); } /** @@ -695,7 +695,7 @@ private: void add_locks_from_other(const cuckoohash_map &other) { locks_t &other_locks = other.get_current_locks(); - all_locks_.emplace_back(other_locks.size(), spinlock(), get_allocator()); + all_locks_.emplace_back(other_locks.size(), get_allocator()); std::copy(other_locks.begin(), other_locks.end(), get_current_locks().begin()); } @@ -794,7 +794,7 @@ private: // under this lock. One can compute the size of the table by summing the // elem_counter over all locks. // - // - is_migrated: When resizing with cuckoo_fast_doulbe, we do not + // - is_migrated: When resizing with cuckoo_fast_double, we do not // immediately rehash elements from the old buckets array to the new one. // Instead, we'll mark all of the locks as not migrated. So anybody trying to // acquire the lock must also migrate the corresponding buckets if @@ -1823,7 +1823,7 @@ private: } locks_t new_locks(std::min(size_type(kMaxNumLocks), new_bucket_count), - spinlock(), get_allocator()); + get_allocator()); assert(new_locks.size() > current_locks.size()); std::copy(current_locks.begin(), current_locks.end(), new_locks.begin()); for (spinlock &lock : new_locks) { diff --git a/include/json.hpp b/include/json.hpp index e2a68e6f5..87475ab31 100644 --- a/include/json.hpp +++ b/include/json.hpp @@ -1,7 +1,7 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ -| | |__ | | | | | | version 3.7.3 +| | |__ | | | | | | version 3.10.4 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . @@ -31,16 +31,16 @@ SOFTWARE. #define INCLUDE_NLOHMANN_JSON_HPP_ #define NLOHMANN_JSON_VERSION_MAJOR 3 -#define NLOHMANN_JSON_VERSION_MINOR 7 -#define NLOHMANN_JSON_VERSION_PATCH 3 +#define NLOHMANN_JSON_VERSION_MINOR 10 +#define NLOHMANN_JSON_VERSION_PATCH 4 #include // all_of, find, for_each -#include // assert -#include // and, not, or #include // nullptr_t, ptrdiff_t, size_t #include // hash, less #include // initializer_list -#include // istream, ostream +#ifndef JSON_NO_IO + #include // istream, ostream +#endif // JSON_NO_IO #include // random_access_iterator_tag #include // unique_ptr #include // accumulate @@ -51,6 +51,7 @@ SOFTWARE. // #include +#include #include // #include @@ -58,7 +59,6 @@ SOFTWARE. #include // transform #include // array -#include // and, not #include // forward_list #include // inserter, front_inserter, end #include // map @@ -75,41 +75,102 @@ SOFTWARE. #include // exception #include // runtime_error #include // to_string +#include // vector -// #include +// #include +#include // array #include // size_t +#include // uint8_t +#include // string namespace nlohmann { namespace detail { -/// struct to capture the start position of the current token -struct position_t -{ - /// the total number of characters read - std::size_t chars_read_total = 0; - /// the number of characters read in the current line - std::size_t chars_read_current_line = 0; - /// the number of lines read - std::size_t lines_read = 0; +/////////////////////////// +// JSON type enumeration // +/////////////////////////// - /// conversion to size_t to preserve SAX interface - constexpr operator size_t() const - { - return chars_read_total; - } +/*! +@brief the JSON type enumeration + +This enumeration collects the different JSON types. It is internally used to +distinguish the stored values, and the functions @ref basic_json::is_null(), +@ref basic_json::is_object(), @ref basic_json::is_array(), +@ref basic_json::is_string(), @ref basic_json::is_boolean(), +@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), +@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), +@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and +@ref basic_json::is_structured() rely on it. + +@note There are three enumeration entries (number_integer, number_unsigned, and +number_float), because the library distinguishes these three types for numbers: +@ref basic_json::number_unsigned_t is used for unsigned integers, +@ref basic_json::number_integer_t is used for signed integers, and +@ref basic_json::number_float_t is used for floating-point numbers or to +approximate integers which do not fit in the limits of their respective type. + +@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON +value with the default value for a given type + +@since version 1.0.0 +*/ +enum class value_t : std::uint8_t +{ + null, ///< null value + object, ///< object (unordered set of name/value pairs) + array, ///< array (ordered collection of values) + string, ///< string value + boolean, ///< boolean value + number_integer, ///< number value (signed integer) + number_unsigned, ///< number value (unsigned integer) + number_float, ///< number value (floating-point) + binary, ///< binary array (ordered collection of bytes) + discarded ///< discarded by the parser callback function }; -} // namespace detail -} // namespace nlohmann +/*! +@brief comparison operator for JSON types + +Returns an ordering that is similar to Python: +- order: null < boolean < number < object < array < string < binary +- furthermore, each type is not smaller than itself +- discarded values are not comparable +- binary is represented as a b"" string in python and directly comparable to a + string; however, making a binary array directly comparable with a string would + be surprising behavior in a JSON file. + +@since version 1.0.0 +*/ +inline bool operator<(const value_t lhs, const value_t rhs) noexcept +{ + static constexpr std::array order = {{ + 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, + 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, + 6 /* binary */ + } + }; + + const auto l_index = static_cast(lhs); + const auto r_index = static_cast(rhs); + return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; +} +} // namespace detail +} // namespace nlohmann + +// #include + +#include // #include -#include // pair +#include // declval, pair // #include + + /* Hedley - https://nemequ.github.io/hedley * Created by Evan Nemerson * @@ -122,11 +183,11 @@ struct position_t * SPDX-License-Identifier: CC0-1.0 */ -#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 11) +#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15) #if defined(JSON_HEDLEY_VERSION) #undef JSON_HEDLEY_VERSION #endif -#define JSON_HEDLEY_VERSION 11 +#define JSON_HEDLEY_VERSION 15 #if defined(JSON_HEDLEY_STRINGIFY_EX) #undef JSON_HEDLEY_STRINGIFY_EX @@ -148,6 +209,16 @@ struct position_t #endif #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) +#if defined(JSON_HEDLEY_CONCAT3_EX) + #undef JSON_HEDLEY_CONCAT3_EX +#endif +#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c + +#if defined(JSON_HEDLEY_CONCAT3) + #undef JSON_HEDLEY_CONCAT3 +#endif +#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c) + #if defined(JSON_HEDLEY_VERSION_ENCODE) #undef JSON_HEDLEY_VERSION_ENCODE #endif @@ -189,18 +260,18 @@ struct position_t #if defined(JSON_HEDLEY_MSVC_VERSION) #undef JSON_HEDLEY_MSVC_VERSION #endif -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) +#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL) #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) -#elif defined(_MSC_FULL_VER) +#elif defined(_MSC_FULL_VER) && !defined(__ICL) #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) && !defined(__ICL) #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) #endif #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) #undef JSON_HEDLEY_MSVC_VERSION_CHECK #endif -#if !defined(_MSC_VER) +#if !defined(JSON_HEDLEY_MSVC_VERSION) #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) #elif defined(_MSC_VER) && (_MSC_VER >= 1400) #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) @@ -213,9 +284,9 @@ struct position_t #if defined(JSON_HEDLEY_INTEL_VERSION) #undef JSON_HEDLEY_INTEL_VERSION #endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) +#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL) #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) -#elif defined(__INTEL_COMPILER) +#elif defined(__INTEL_COMPILER) && !defined(__ICL) #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) #endif @@ -228,6 +299,22 @@ struct position_t #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) #endif +#if defined(JSON_HEDLEY_INTEL_CL_VERSION) + #undef JSON_HEDLEY_INTEL_CL_VERSION +#endif +#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL) + #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0) +#endif + +#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK) + #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_INTEL_CL_VERSION) + #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0) +#endif + #if defined(JSON_HEDLEY_PGI_VERSION) #undef JSON_HEDLEY_PGI_VERSION #endif @@ -323,9 +410,17 @@ struct position_t #if defined(JSON_HEDLEY_TI_VERSION) #undef JSON_HEDLEY_TI_VERSION #endif -#if defined(__TI_COMPILER_VERSION__) +#if \ + defined(__TI_COMPILER_VERSION__) && \ + ( \ + defined(__TMS470__) || defined(__TI_ARM__) || \ + defined(__MSP430__) || \ + defined(__TMS320C2000__) \ + ) +#if (__TI_COMPILER_VERSION__ >= 16000000) #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) #endif +#endif #if defined(JSON_HEDLEY_TI_VERSION_CHECK) #undef JSON_HEDLEY_TI_VERSION_CHECK @@ -336,6 +431,102 @@ struct position_t #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) #endif +#if defined(JSON_HEDLEY_TI_CL2000_VERSION) + #undef JSON_HEDLEY_TI_CL2000_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__) + #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL2000_VERSION) + #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL430_VERSION) + #undef JSON_HEDLEY_TI_CL430_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) + #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL430_VERSION) + #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) + #undef JSON_HEDLEY_TI_ARMCL_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__)) + #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK) + #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) + #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL6X_VERSION) + #undef JSON_HEDLEY_TI_CL6X_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__) + #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL6X_VERSION) + #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL7X_VERSION) + #undef JSON_HEDLEY_TI_CL7X_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__) + #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL7X_VERSION) + #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) + #undef JSON_HEDLEY_TI_CLPRU_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__) + #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) + #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0) +#endif + #if defined(JSON_HEDLEY_CRAY_VERSION) #undef JSON_HEDLEY_CRAY_VERSION #endif @@ -363,7 +554,7 @@ struct position_t #if __VER__ > 1000 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) #else - #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0) + #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0) #endif #endif @@ -440,6 +631,22 @@ struct position_t #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) #endif +#if defined(JSON_HEDLEY_MCST_LCC_VERSION) + #undef JSON_HEDLEY_MCST_LCC_VERSION +#endif +#if defined(__LCC__) && defined(__LCC_MINOR__) + #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__) +#endif + +#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK) + #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_MCST_LCC_VERSION) + #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0) +#endif + #if defined(JSON_HEDLEY_GCC_VERSION) #undef JSON_HEDLEY_GCC_VERSION #endif @@ -449,8 +656,16 @@ struct position_t !defined(JSON_HEDLEY_INTEL_VERSION) && \ !defined(JSON_HEDLEY_PGI_VERSION) && \ !defined(JSON_HEDLEY_ARM_VERSION) && \ + !defined(JSON_HEDLEY_CRAY_VERSION) && \ !defined(JSON_HEDLEY_TI_VERSION) && \ - !defined(__COMPCERT__) + !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL430_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ + !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ + !defined(__COMPCERT__) && \ + !defined(JSON_HEDLEY_MCST_LCC_VERSION) #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION #endif @@ -466,17 +681,21 @@ struct position_t #if defined(JSON_HEDLEY_HAS_ATTRIBUTE) #undef JSON_HEDLEY_HAS_ATTRIBUTE #endif -#if defined(__has_attribute) - #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) +#if \ + defined(__has_attribute) && \ + ( \ + (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \ + ) +# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) #else - #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) +# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) #endif #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE #endif #if defined(__has_attribute) - #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute) + #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) #else #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) #endif @@ -485,7 +704,7 @@ struct position_t #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE #endif #if defined(__has_attribute) - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute) + #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) #else #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) #endif @@ -509,6 +728,7 @@ struct position_t #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) #elif \ !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_IAR_VERSION) && \ (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) @@ -669,21 +889,6 @@ struct position_t #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) #endif -/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ -#endif -#if defined(__cplusplus) && JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -#else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x -#endif - #if \ (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ defined(__clang__) || \ @@ -692,7 +897,13 @@ struct position_t JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ @@ -719,13 +930,21 @@ struct position_t #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") -#elif JSON_HEDLEY_TI_VERSION_CHECK(8,1,0) +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) @@ -736,6 +955,102 @@ struct position_t #define JSON_HEDLEY_DIAGNOSTIC_POP #endif +/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for + HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ +#endif +#if defined(__cplusplus) +# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") +# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") +# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions") +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ + _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# endif +# else +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# endif +# endif +#endif +#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x +#endif + +#if defined(JSON_HEDLEY_CONST_CAST) + #undef JSON_HEDLEY_CONST_CAST +#endif +#if defined(__cplusplus) +# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) +#elif \ + JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ + ((T) (expr)); \ + JSON_HEDLEY_DIAGNOSTIC_POP \ + })) +#else +# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_REINTERPRET_CAST) + #undef JSON_HEDLEY_REINTERPRET_CAST +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) +#else + #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_STATIC_CAST) + #undef JSON_HEDLEY_STATIC_CAST +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) +#else + #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_CPP_CAST) + #undef JSON_HEDLEY_CPP_CAST +#endif +#if defined(__cplusplus) +# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast") +# define JSON_HEDLEY_CPP_CAST(T, expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ + ((T) (expr)) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0) +# define JSON_HEDLEY_CPP_CAST(T, expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("diag_suppress=Pe137") \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) +# endif +#else +# define JSON_HEDLEY_CPP_CAST(T, expr) (expr) +#endif + #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED #endif @@ -743,13 +1058,30 @@ struct position_t #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445") #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) -#elif JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") @@ -770,16 +1102,26 @@ struct position_t #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161)) #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) -#elif JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161") #else #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS #endif @@ -793,14 +1135,25 @@ struct position_t #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292)) #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098") #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") -#elif JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097") +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") #else #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES #endif @@ -818,39 +1171,73 @@ struct position_t #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL #endif +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunused-function") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505)) +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION +#endif + #if defined(JSON_HEDLEY_DEPRECATED) #undef JSON_HEDLEY_DEPRECATED #endif #if defined(JSON_HEDLEY_DEPRECATED_FOR) #undef JSON_HEDLEY_DEPRECATED_FOR #endif -#if defined(__cplusplus) && (__cplusplus >= 201402L) - #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) +#if \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) #elif \ - JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \ + (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(8,3,0) + JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) +#elif defined(__cplusplus) && (__cplusplus >= 201402L) + #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) #elif \ JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) - #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) #elif \ JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) + JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) @@ -867,7 +1254,8 @@ struct position_t #if \ JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) #else #define JSON_HEDLEY_UNAVAILABLE(available_since) @@ -876,21 +1264,41 @@ struct position_t #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) #undef JSON_HEDLEY_WARN_UNUSED_RESULT #endif -#if defined(__cplusplus) && (__cplusplus >= 201703L) - #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) -#elif \ +#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) + #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG +#endif +#if \ JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__)) +#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L) + #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]]) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) + #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) #elif defined(_Check_return_) /* SAL */ #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_ #else #define JSON_HEDLEY_WARN_UNUSED_RESULT + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) #endif #if defined(JSON_HEDLEY_SENTINEL) @@ -900,7 +1308,8 @@ struct position_t JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) + JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) #else #define JSON_HEDLEY_SENTINEL(position) @@ -911,7 +1320,9 @@ struct position_t #endif #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) #define JSON_HEDLEY_NO_RETURN __noreturn -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +#elif \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L #define JSON_HEDLEY_NO_RETURN _Noreturn @@ -923,14 +1334,26 @@ struct position_t JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(18,0,0) || \ - (JSON_HEDLEY_TI_VERSION_CHECK(17,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus) +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) #define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) @@ -955,54 +1378,57 @@ struct position_t #if defined(JSON_HEDLEY_UNREACHABLE_RETURN) #undef JSON_HEDLEY_UNREACHABLE_RETURN #endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) - #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) - #define JSON_HEDLEY_UNREACHABLE() __assume(0) -#elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) - #if defined(__cplusplus) - #define JSON_HEDLEY_UNREACHABLE() std::_nassert(0) - #else - #define JSON_HEDLEY_UNREACHABLE() _nassert(0) - #endif - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return value -#elif defined(EXIT_FAILURE) - #define JSON_HEDLEY_UNREACHABLE() abort() -#else - #define JSON_HEDLEY_UNREACHABLE() - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return value -#endif -#if !defined(JSON_HEDLEY_UNREACHABLE_RETURN) - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() -#endif - #if defined(JSON_HEDLEY_ASSUME) #undef JSON_HEDLEY_ASSUME #endif #if \ JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_ASSUME(expr) __assume(expr) #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) -#elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) +#elif \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) #if defined(__cplusplus) #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) #else #define JSON_HEDLEY_ASSUME(expr) _nassert(expr) #endif -#elif \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && !defined(JSON_HEDLEY_ARM_VERSION)) || \ +#endif +#if \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) - #define JSON_HEDLEY_ASSUME(expr) ((void) ((expr) ? 1 : (__builtin_unreachable(), 1))) + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() +#elif defined(JSON_HEDLEY_ASSUME) + #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) +#endif +#if !defined(JSON_HEDLEY_ASSUME) + #if defined(JSON_HEDLEY_UNREACHABLE) + #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1))) + #else + #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr) + #endif +#endif +#if defined(JSON_HEDLEY_UNREACHABLE) + #if \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value)) + #else + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() + #endif #else - #define JSON_HEDLEY_ASSUME(expr) ((void) (expr)) + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value) +#endif +#if !defined(JSON_HEDLEY_UNREACHABLE) + #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) #endif JSON_HEDLEY_DIAGNOSTIC_PUSH @@ -1046,8 +1472,18 @@ JSON_HEDLEY_DIAGNOSTIC_POP JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) @@ -1080,44 +1516,50 @@ JSON_HEDLEY_DIAGNOSTIC_POP #undef JSON_HEDLEY_UNPREDICTABLE #endif #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) - #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable(!!(expr)) + #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) #endif #if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) -# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(expr, value, probability) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1, probability) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0, probability) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) -#if !defined(JSON_HEDLEY_BUILTIN_UNPREDICTABLE) - #define JSON_HEDLEY_BUILTIN_UNPREDICTABLE(expr) __builtin_expect_with_probability(!!(expr), 1, 0.5) -#endif + (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability)) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability)) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability)) +# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 ) +# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 ) #elif \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) || \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) # define JSON_HEDLEY_PREDICT(expr, expected, probability) \ - (((probability) >= 0.9) ? __builtin_expect(!!(expr), (expected)) : (((void) (expected)), !!(expr))) + (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))) # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ (__extension__ ({ \ - JSON_HEDLEY_CONSTEXPR double hedley_probability_ = (probability); \ + double hedley_probability_ = (probability); \ ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ })) # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ (__extension__ ({ \ - JSON_HEDLEY_CONSTEXPR double hedley_probability_ = (probability); \ + double hedley_probability_ = (probability); \ ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ })) # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) #else -# define JSON_HEDLEY_PREDICT(expr, expected, probability) (((void) (expected)), !!(expr)) +# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)) # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) # define JSON_HEDLEY_LIKELY(expr) (!!(expr)) @@ -1137,12 +1579,24 @@ JSON_HEDLEY_DIAGNOSTIC_POP JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(14, 0, 0) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_MALLOC __declspec(restrict) #else #define JSON_HEDLEY_MALLOC @@ -1152,22 +1606,37 @@ JSON_HEDLEY_DIAGNOSTIC_POP #undef JSON_HEDLEY_PURE #endif #if \ - JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_PURE __attribute__((__pure__)) + JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PURE __attribute__((__pure__)) #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") -#elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") +# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") +#elif defined(__cplusplus) && \ + ( \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \ + ) +# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") #else - #define JSON_HEDLEY_PURE +# define JSON_HEDLEY_PURE #endif #if defined(JSON_HEDLEY_CONST) @@ -1180,9 +1649,19 @@ JSON_HEDLEY_DIAGNOSTIC_POP JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_CONST __attribute__((__const__)) #elif \ JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) @@ -1200,13 +1679,18 @@ JSON_HEDLEY_DIAGNOSTIC_POP JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - defined(__clang__) + defined(__clang__) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_RESTRICT __restrict #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) #define JSON_HEDLEY_RESTRICT _Restrict @@ -1227,8 +1711,15 @@ JSON_HEDLEY_DIAGNOSTIC_POP #define JSON_HEDLEY_INLINE __inline__ #elif \ JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_INLINE __inline #else #define JSON_HEDLEY_INLINE @@ -1238,23 +1729,44 @@ JSON_HEDLEY_DIAGNOSTIC_POP #undef JSON_HEDLEY_ALWAYS_INLINE #endif #if \ - JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) - #define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) - #define JSON_HEDLEY_ALWAYS_INLINE __forceinline -#elif JSON_HEDLEY_TI_VERSION_CHECK(7,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") + JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) +# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_ALWAYS_INLINE __forceinline +#elif defined(__cplusplus) && \ + ( \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \ + ) +# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") +# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") #else - #define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE +# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE #endif #if defined(JSON_HEDLEY_NEVER_INLINE) @@ -1267,14 +1779,27 @@ JSON_HEDLEY_DIAGNOSTIC_POP JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") -#elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus) +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") @@ -1296,26 +1821,32 @@ JSON_HEDLEY_DIAGNOSTIC_POP #undef JSON_HEDLEY_IMPORT #endif #if defined(_WIN32) || defined(__CYGWIN__) - #define JSON_HEDLEY_PRIVATE - #define JSON_HEDLEY_PUBLIC __declspec(dllexport) - #define JSON_HEDLEY_IMPORT __declspec(dllimport) +# define JSON_HEDLEY_PRIVATE +# define JSON_HEDLEY_PUBLIC __declspec(dllexport) +# define JSON_HEDLEY_IMPORT __declspec(dllimport) #else - #if \ - JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_EABI__) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) - #define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) - #define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) - #else - #define JSON_HEDLEY_PRIVATE - #define JSON_HEDLEY_PUBLIC - #endif - #define JSON_HEDLEY_IMPORT extern +# if \ + JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + ( \ + defined(__TI_EABI__) && \ + ( \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \ + ) \ + ) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) +# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) +# else +# define JSON_HEDLEY_PRIVATE +# define JSON_HEDLEY_PUBLIC +# endif +# define JSON_HEDLEY_IMPORT extern #endif #if defined(JSON_HEDLEY_NO_THROW) @@ -1324,10 +1855,12 @@ JSON_HEDLEY_DIAGNOSTIC_POP #if \ JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) #elif \ JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) #define JSON_HEDLEY_NO_THROW __declspec(nothrow) #else @@ -1337,7 +1870,10 @@ JSON_HEDLEY_DIAGNOSTIC_POP #if defined(JSON_HEDLEY_FALL_THROUGH) #undef JSON_HEDLEY_FALL_THROUGH #endif -#if JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(fallthrough,7,0,0) && !defined(JSON_HEDLEY_PGI_VERSION) +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) @@ -1354,7 +1890,8 @@ JSON_HEDLEY_DIAGNOSTIC_POP #endif #if \ JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) + JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) #elif defined(_Ret_notnull_) /* SAL */ #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ @@ -1394,9 +1931,10 @@ JSON_HEDLEY_DIAGNOSTIC_POP JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) #endif #if !defined(__cplusplus) @@ -1415,8 +1953,12 @@ JSON_HEDLEY_DIAGNOSTIC_POP #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) #endif # elif \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && !defined(JSON_HEDLEY_SUNPRO_VERSION) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ - JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \ + ( \ + defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ + !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_IAR_VERSION)) || \ + (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ @@ -1431,7 +1973,12 @@ JSON_HEDLEY_DIAGNOSTIC_POP defined(JSON_HEDLEY_GCC_VERSION) || \ defined(JSON_HEDLEY_INTEL_VERSION) || \ defined(JSON_HEDLEY_TINYC_VERSION) || \ - defined(JSON_HEDLEY_TI_VERSION) || \ + defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \ + defined(JSON_HEDLEY_TI_CL2000_VERSION) || \ + defined(JSON_HEDLEY_TI_CL6X_VERSION) || \ + defined(JSON_HEDLEY_TI_CL7X_VERSION) || \ + defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \ defined(__clang__) # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ sizeof(void) != \ @@ -1481,7 +2028,7 @@ JSON_HEDLEY_DIAGNOSTIC_POP #if \ !defined(__cplusplus) && ( \ (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ - JSON_HEDLEY_HAS_FEATURE(c_static_assert) || \ + (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ defined(_Static_assert) \ @@ -1490,58 +2037,12 @@ JSON_HEDLEY_DIAGNOSTIC_POP #elif \ (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ - (defined(__cplusplus) && JSON_HEDLEY_TI_VERSION_CHECK(8,3,0)) + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) #else # define JSON_HEDLEY_STATIC_ASSERT(expr, message) #endif -#if defined(JSON_HEDLEY_CONST_CAST) - #undef JSON_HEDLEY_CONST_CAST -#endif -#if defined(__cplusplus) -# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) -#elif \ - JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_REINTERPRET_CAST) - #undef JSON_HEDLEY_REINTERPRET_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) -#else - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (*((T*) &(expr))) -#endif - -#if defined(JSON_HEDLEY_STATIC_CAST) - #undef JSON_HEDLEY_STATIC_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) -#else - #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_CPP_CAST) - #undef JSON_HEDLEY_CPP_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_CPP_CAST(T, expr) static_cast(expr) -#else - #define JSON_HEDLEY_CPP_CAST(T, expr) (expr) -#endif - #if defined(JSON_HEDLEY_NULL) #undef JSON_HEDLEY_NULL #endif @@ -1593,9 +2094,12 @@ JSON_HEDLEY_DIAGNOSTIC_POP JSON_HEDLEY_DIAGNOSTIC_POP #elif \ JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) + JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) #else # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) @@ -1631,8 +2135,10 @@ JSON_HEDLEY_DIAGNOSTIC_POP #if defined(JSON_HEDLEY_FLAGS) #undef JSON_HEDLEY_FLAGS #endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) +#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion")) #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) +#else + #define JSON_HEDLEY_FLAGS #endif #if defined(JSON_HEDLEY_FLAGS_CAST) @@ -1652,7 +2158,9 @@ JSON_HEDLEY_DIAGNOSTIC_POP #if defined(JSON_HEDLEY_EMPTY_BASES) #undef JSON_HEDLEY_EMPTY_BASES #endif -#if JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0) +#if \ + (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) #else #define JSON_HEDLEY_EMPTY_BASES @@ -1706,6 +2214,83 @@ JSON_HEDLEY_DIAGNOSTIC_POP #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ +// #include + + +#include + +// #include + + +namespace nlohmann +{ +namespace detail +{ +template struct make_void +{ + using type = void; +}; +template using void_t = typename make_void::type; +} // namespace detail +} // namespace nlohmann + + +// https://en.cppreference.com/w/cpp/experimental/is_detected +namespace nlohmann +{ +namespace detail +{ +struct nonesuch +{ + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const&) = delete; + nonesuch(nonesuch const&&) = delete; + void operator=(nonesuch const&) = delete; + void operator=(nonesuch&&) = delete; +}; + +template class Op, + class... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +template class Op, class... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +template class Op, class... Args> +using is_detected = typename detector::value_t; + +template class Op, class... Args> +struct is_detected_lazy : is_detected { }; + +template class Op, class... Args> +using detected_t = typename detector::type; + +template class Op, class... Args> +using detected_or = detector; + +template class Op, class... Args> +using detected_or_t = typename detected_or::type; + +template class Op, class... Args> +using is_detected_exact = std::is_same>; + +template class Op, class... Args> +using is_detected_convertible = + std::is_convertible, To>; +} // namespace detail +} // namespace nlohmann + // This file contains all internal macro definitions // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them @@ -1724,23 +2309,27 @@ JSON_HEDLEY_DIAGNOSTIC_POP #endif // C++ language standard detection -#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 -#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) - #define JSON_HAS_CPP_14 -#endif - -// disable float-equal warnings on GCC/clang -#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wfloat-equal" +// if the user manually specified the used c++ version this is skipped +#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) + #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) + #define JSON_HAS_CPP_20 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) + #define JSON_HAS_CPP_14 + #endif + // the cpp 11 flag is always specified because it is the minimal required version + #define JSON_HAS_CPP_11 #endif // disable documentation warnings on clang #if defined(__clang__) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdocumentation" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdocumentation" + #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" #endif // allow to disable exceptions @@ -1777,6 +2366,19 @@ JSON_HEDLEY_DIAGNOSTIC_POP #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER #endif +// allow to override assert +#if !defined(JSON_ASSERT) + #include // assert + #define JSON_ASSERT(x) assert(x) +#endif + +// allow to access some private functions (needed by the test suite) +#if defined(JSON_TESTS_PRIVATE) + #define JSON_PRIVATE_UNLESS_TESTED public +#else + #define JSON_PRIVATE_UNLESS_TESTED private +#endif + /*! @brief macro to briefly define a mapping between an enum and JSON @def NLOHMANN_JSON_SERIALIZE_ENUM @@ -1817,72 +2419,434 @@ JSON_HEDLEY_DIAGNOSTIC_POP class StringType, class BooleanType, class NumberIntegerType, \ class NumberUnsignedType, class NumberFloatType, \ template class AllocatorType, \ - template class JSONSerializer> + template class JSONSerializer, \ + class BinaryType> #define NLOHMANN_BASIC_JSON_TPL \ basic_json + AllocatorType, JSONSerializer, BinaryType> + +// Macros to simplify conversion from/to types + +#define NLOHMANN_JSON_EXPAND( x ) x +#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME +#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ + NLOHMANN_JSON_PASTE64, \ + NLOHMANN_JSON_PASTE63, \ + NLOHMANN_JSON_PASTE62, \ + NLOHMANN_JSON_PASTE61, \ + NLOHMANN_JSON_PASTE60, \ + NLOHMANN_JSON_PASTE59, \ + NLOHMANN_JSON_PASTE58, \ + NLOHMANN_JSON_PASTE57, \ + NLOHMANN_JSON_PASTE56, \ + NLOHMANN_JSON_PASTE55, \ + NLOHMANN_JSON_PASTE54, \ + NLOHMANN_JSON_PASTE53, \ + NLOHMANN_JSON_PASTE52, \ + NLOHMANN_JSON_PASTE51, \ + NLOHMANN_JSON_PASTE50, \ + NLOHMANN_JSON_PASTE49, \ + NLOHMANN_JSON_PASTE48, \ + NLOHMANN_JSON_PASTE47, \ + NLOHMANN_JSON_PASTE46, \ + NLOHMANN_JSON_PASTE45, \ + NLOHMANN_JSON_PASTE44, \ + NLOHMANN_JSON_PASTE43, \ + NLOHMANN_JSON_PASTE42, \ + NLOHMANN_JSON_PASTE41, \ + NLOHMANN_JSON_PASTE40, \ + NLOHMANN_JSON_PASTE39, \ + NLOHMANN_JSON_PASTE38, \ + NLOHMANN_JSON_PASTE37, \ + NLOHMANN_JSON_PASTE36, \ + NLOHMANN_JSON_PASTE35, \ + NLOHMANN_JSON_PASTE34, \ + NLOHMANN_JSON_PASTE33, \ + NLOHMANN_JSON_PASTE32, \ + NLOHMANN_JSON_PASTE31, \ + NLOHMANN_JSON_PASTE30, \ + NLOHMANN_JSON_PASTE29, \ + NLOHMANN_JSON_PASTE28, \ + NLOHMANN_JSON_PASTE27, \ + NLOHMANN_JSON_PASTE26, \ + NLOHMANN_JSON_PASTE25, \ + NLOHMANN_JSON_PASTE24, \ + NLOHMANN_JSON_PASTE23, \ + NLOHMANN_JSON_PASTE22, \ + NLOHMANN_JSON_PASTE21, \ + NLOHMANN_JSON_PASTE20, \ + NLOHMANN_JSON_PASTE19, \ + NLOHMANN_JSON_PASTE18, \ + NLOHMANN_JSON_PASTE17, \ + NLOHMANN_JSON_PASTE16, \ + NLOHMANN_JSON_PASTE15, \ + NLOHMANN_JSON_PASTE14, \ + NLOHMANN_JSON_PASTE13, \ + NLOHMANN_JSON_PASTE12, \ + NLOHMANN_JSON_PASTE11, \ + NLOHMANN_JSON_PASTE10, \ + NLOHMANN_JSON_PASTE9, \ + NLOHMANN_JSON_PASTE8, \ + NLOHMANN_JSON_PASTE7, \ + NLOHMANN_JSON_PASTE6, \ + NLOHMANN_JSON_PASTE5, \ + NLOHMANN_JSON_PASTE4, \ + NLOHMANN_JSON_PASTE3, \ + NLOHMANN_JSON_PASTE2, \ + NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) +#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) +#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) +#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) +#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) +#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) +#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) +#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) +#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) +#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) +#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) +#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) +#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) +#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) +#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) +#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) +#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) +#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) +#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) +#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) +#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) +#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) +#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) +#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) +#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) +#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) +#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) +#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) +#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) +#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) +#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) +#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) +#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) +#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) +#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) +#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) +#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) +#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) +#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) +#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) +#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) +#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) +#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) +#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) +#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) +#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) +#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) +#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) +#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) +#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) +#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) +#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) +#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) +#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) +#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) +#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) +#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) +#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) +#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) +#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) +#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) +#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) +#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) +#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) + +#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; +#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_INTRUSIVE +@since version 3.9.0 +*/ +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE +@since version 3.9.0 +*/ +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + + +// inspired from https://stackoverflow.com/a/26745591 +// allows to call any std function as if (e.g. with begin): +// using std::begin; begin(x); +// +// it allows using the detected idiom to retrieve the return type +// of such an expression +#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ + namespace detail { \ + using std::std_name; \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + } \ + \ + namespace detail2 { \ + struct std_name##_tag \ + { \ + }; \ + \ + template \ + std_name##_tag std_name(T&&...); \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + \ + template \ + struct would_call_std_##std_name \ + { \ + static constexpr auto const value = ::nlohmann::detail:: \ + is_detected_exact::value; \ + }; \ + } /* namespace detail2 */ \ + \ + template \ + struct would_call_std_##std_name : detail2::would_call_std_##std_name \ + { \ + } + +#ifndef JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_USE_IMPLICIT_CONVERSIONS 1 +#endif + +#if JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_EXPLICIT +#else + #define JSON_EXPLICIT explicit +#endif + +#ifndef JSON_DIAGNOSTICS + #define JSON_DIAGNOSTICS 0 +#endif namespace nlohmann { namespace detail { -//////////////// -// exceptions // -//////////////// /*! -@brief general exception of the @ref basic_json class - -This class is an extension of `std::exception` objects with a member @a id for -exception ids. It is used as the base class for all exceptions thrown by the -@ref basic_json class. This class can hence be used as "wildcard" to catch -exceptions. - -Subclasses: -- @ref parse_error for exceptions indicating a parse error -- @ref invalid_iterator for exceptions indicating errors with iterators -- @ref type_error for exceptions indicating executing a member function with - a wrong type -- @ref out_of_range for exceptions indicating access out of the defined range -- @ref other_error for exceptions indicating other library errors +@brief replace all occurrences of a substring by another string -@internal -@note To have nothrow-copy-constructible exceptions, we internally use - `std::runtime_error` which can cope with arbitrary-length error messages. - Intermediate strings are built with static functions and then passed to - the actual constructor. -@endinternal +@param[in,out] s the string to manipulate; changed so that all + occurrences of @a f are replaced with @a t +@param[in] f the substring to replace with @a t +@param[in] t the string to replace @a f -@liveexample{The following code shows how arbitrary library exceptions can be -caught.,exception} +@pre The search string @a f must not be empty. **This precondition is +enforced with an assertion.** -@since version 3.0.0 +@since version 2.0.0 */ -class exception : public std::exception +inline void replace_substring(std::string& s, const std::string& f, + const std::string& t) { - public: - /// returns the explanatory string - JSON_HEDLEY_RETURNS_NON_NULL - const char* what() const noexcept override - { - return m.what(); - } + JSON_ASSERT(!f.empty()); + for (auto pos = s.find(f); // find first occurrence of f + pos != std::string::npos; // make sure f was found + s.replace(pos, f.size(), t), // replace with t, and + pos = s.find(f, pos + t.size())) // find next occurrence of f + {} +} - /// the id of the exception - const int id; +/*! + * @brief string escaping as described in RFC 6901 (Sect. 4) + * @param[in] s string to escape + * @return escaped string + * + * Note the order of escaping "~" to "~0" and "/" to "~1" is important. + */ +inline std::string escape(std::string s) +{ + replace_substring(s, "~", "~0"); + replace_substring(s, "/", "~1"); + return s; +} - protected: - JSON_HEDLEY_NON_NULL(3) - exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} +/*! + * @brief string unescaping as described in RFC 6901 (Sect. 4) + * @param[in] s string to unescape + * @return unescaped string + * + * Note the order of escaping "~1" to "/" and "~0" to "~" is important. + */ +static void unescape(std::string& s) +{ + replace_substring(s, "~1", "/"); + replace_substring(s, "~0", "~"); +} + +} // namespace detail +} // namespace nlohmann + +// #include + + +#include // size_t + +namespace nlohmann +{ +namespace detail +{ +/// struct to capture the start position of the current token +struct position_t +{ + /// the total number of characters read + std::size_t chars_read_total = 0; + /// the number of characters read in the current line + std::size_t chars_read_current_line = 0; + /// the number of lines read + std::size_t lines_read = 0; + + /// conversion to size_t to preserve SAX interface + constexpr operator size_t() const + { + return chars_read_total; + } +}; + +} // namespace detail +} // namespace nlohmann + +// #include + + +namespace nlohmann +{ +namespace detail +{ +//////////////// +// exceptions // +//////////////// + +/*! +@brief general exception of the @ref basic_json class + +This class is an extension of `std::exception` objects with a member @a id for +exception ids. It is used as the base class for all exceptions thrown by the +@ref basic_json class. This class can hence be used as "wildcard" to catch +exceptions. + +Subclasses: +- @ref parse_error for exceptions indicating a parse error +- @ref invalid_iterator for exceptions indicating errors with iterators +- @ref type_error for exceptions indicating executing a member function with + a wrong type +- @ref out_of_range for exceptions indicating access out of the defined range +- @ref other_error for exceptions indicating other library errors + +@internal +@note To have nothrow-copy-constructible exceptions, we internally use + `std::runtime_error` which can cope with arbitrary-length error messages. + Intermediate strings are built with static functions and then passed to + the actual constructor. +@endinternal + +@liveexample{The following code shows how arbitrary library exceptions can be +caught.,exception} + +@since version 3.0.0 +*/ +class exception : public std::exception +{ + public: + /// returns the explanatory string + const char* what() const noexcept override + { + return m.what(); + } + + /// the id of the exception + const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes) + + protected: + JSON_HEDLEY_NON_NULL(3) + exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} static std::string name(const std::string& ename, int id_) { return "[json.exception." + ename + "." + std::to_string(id_) + "] "; } + template + static std::string diagnostics(const BasicJsonType& leaf_element) + { +#if JSON_DIAGNOSTICS + std::vector tokens; + for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent) + { + switch (current->m_parent->type()) + { + case value_t::array: + { + for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i) + { + if (¤t->m_parent->m_value.array->operator[](i) == current) + { + tokens.emplace_back(std::to_string(i)); + break; + } + } + break; + } + + case value_t::object: + { + for (const auto& element : *current->m_parent->m_value.object) + { + if (&element.second == current) + { + tokens.emplace_back(element.first.c_str()); + break; + } + } + break; + } + + case value_t::null: // LCOV_EXCL_LINE + case value_t::string: // LCOV_EXCL_LINE + case value_t::boolean: // LCOV_EXCL_LINE + case value_t::number_integer: // LCOV_EXCL_LINE + case value_t::number_unsigned: // LCOV_EXCL_LINE + case value_t::number_float: // LCOV_EXCL_LINE + case value_t::binary: // LCOV_EXCL_LINE + case value_t::discarded: // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + break; // LCOV_EXCL_LINE + } + } + + if (tokens.empty()) + { + return ""; + } + + return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{}, + [](const std::string & a, const std::string & b) + { + return a + "/" + detail::escape(b); + }) + ") "; +#else + static_cast(leaf_element); + return ""; +#endif + } + private: /// an exception object as storage for error messages std::runtime_error m; @@ -1915,6 +2879,7 @@ json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vect json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read. json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read. json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet). +json.exception.parse_error.115 | parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A | A UBJSON high-precision number could not be parsed. @note For an input with n bytes, 1 is the index of the first character and n+1 is the index of the terminating null byte or the end of file. This also @@ -1944,18 +2909,20 @@ class parse_error : public exception @param[in] what_arg the explanatory string @return parse_error object */ - static parse_error create(int id_, const position_t& pos, const std::string& what_arg) + template + static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context) { std::string w = exception::name("parse_error", id_) + "parse error" + - position_string(pos) + ": " + what_arg; + position_string(pos) + ": " + exception::diagnostics(context) + what_arg; return parse_error(id_, pos.chars_read_total, w.c_str()); } - static parse_error create(int id_, std::size_t byte_, const std::string& what_arg) + template + static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context) { std::string w = exception::name("parse_error", id_) + "parse error" + (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") + - ": " + what_arg; + ": " + exception::diagnostics(context) + what_arg; return parse_error(id_, byte_, w.c_str()); } @@ -2021,9 +2988,10 @@ caught.,invalid_iterator} class invalid_iterator : public exception { public: - static invalid_iterator create(int id_, const std::string& what_arg) + template + static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context) { - std::string w = exception::name("invalid_iterator", id_) + what_arg; + std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg; return invalid_iterator(id_, w.c_str()); } @@ -2075,9 +3043,10 @@ caught.,type_error} class type_error : public exception { public: - static type_error create(int id_, const std::string& what_arg) + template + static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context) { - std::string w = exception::name("type_error", id_) + what_arg; + std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg; return type_error(id_, w.c_str()); } @@ -2103,7 +3072,7 @@ json.exception.out_of_range.403 | key 'foo' not found | The provided key was not json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved. json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value. json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF. -json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. | +json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. (until version 3.8.0) | json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. | json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string | @@ -2122,9 +3091,10 @@ caught.,out_of_range} class out_of_range : public exception { public: - static out_of_range create(int id_, const std::string& what_arg) + template + static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context) { - std::string w = exception::name("out_of_range", id_) + what_arg; + std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg; return out_of_range(id_, w.c_str()); } @@ -2160,9 +3130,10 @@ caught.,other_error} class other_error : public exception { public: - static other_error create(int id_, const std::string& what_arg) + template + static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context) { - std::string w = exception::name("other_error", id_) + what_arg; + std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg; return other_error(id_, w.c_str()); } @@ -2178,52 +3149,143 @@ class other_error : public exception // #include -#include // not #include // size_t #include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type +#include // index_sequence, make_index_sequence, index_sequence_for + +// #include + namespace nlohmann { namespace detail { + +template +using uncvref_t = typename std::remove_cv::type>::type; + +#ifdef JSON_HAS_CPP_14 + +// the following utilities are natively available in C++14 +using std::enable_if_t; +using std::index_sequence; +using std::make_index_sequence; +using std::index_sequence_for; + +#else + // alias templates to reduce boilerplate template using enable_if_t = typename std::enable_if::type; -template -using uncvref_t = typename std::remove_cv::type>::type; +// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h +// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. + +//// START OF CODE FROM GOOGLE ABSEIL -// implementation of C++14 index_sequence and affiliates -// source: https://stackoverflow.com/a/32223343 -template -struct index_sequence +// integer_sequence +// +// Class template representing a compile-time integer sequence. An instantiation +// of `integer_sequence` has a sequence of integers encoded in its +// type through its template arguments (which is a common need when +// working with C++11 variadic templates). `absl::integer_sequence` is designed +// to be a drop-in replacement for C++14's `std::integer_sequence`. +// +// Example: +// +// template< class T, T... Ints > +// void user_function(integer_sequence); +// +// int main() +// { +// // user_function's `T` will be deduced to `int` and `Ints...` +// // will be deduced to `0, 1, 2, 3, 4`. +// user_function(make_integer_sequence()); +// } +template +struct integer_sequence { - using type = index_sequence; - using value_type = std::size_t; + using value_type = T; static constexpr std::size_t size() noexcept { return sizeof...(Ints); } }; -template -struct merge_and_renumber; +// index_sequence +// +// A helper template for an `integer_sequence` of `size_t`, +// `absl::index_sequence` is designed to be a drop-in replacement for C++14's +// `std::index_sequence`. +template +using index_sequence = integer_sequence; + +namespace utility_internal +{ + +template +struct Extend; + +// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. +template +struct Extend, SeqSize, 0> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; +}; + +template +struct Extend, SeqSize, 1> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; +}; + +// Recursion helper for 'make_integer_sequence'. +// 'Gen::type' is an alias for 'integer_sequence'. +template +struct Gen +{ + using type = + typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; +}; + +template +struct Gen +{ + using type = integer_sequence; +}; + +} // namespace utility_internal -template -struct merge_and_renumber, index_sequence> - : index_sequence < I1..., (sizeof...(I1) + I2)... > {}; +// Compile-time sequences of integers -template -struct make_index_sequence - : merge_and_renumber < typename make_index_sequence < N / 2 >::type, - typename make_index_sequence < N - N / 2 >::type > {}; +// make_integer_sequence +// +// This template alias is equivalent to +// `integer_sequence`, and is designed to be a drop-in +// replacement for C++14's `std::make_integer_sequence`. +template +using make_integer_sequence = typename utility_internal::Gen::type; -template<> struct make_index_sequence<0> : index_sequence<> {}; -template<> struct make_index_sequence<1> : index_sequence<0> {}; +// make_index_sequence +// +// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, +// and is designed to be a drop-in replacement for C++14's +// `std::make_index_sequence`. +template +using make_index_sequence = make_integer_sequence; -template +// index_sequence_for +// +// Converts a typename pack into an index sequence of the same length, and +// is designed to be a drop-in replacement for C++14's +// `std::index_sequence_for()` +template using index_sequence_for = make_index_sequence; +//// END OF CODE FROM GOOGLE ABSEIL + +#endif + // dispatch utility (taken from ranges-v3) template struct priority_tag : priority_tag < N - 1 > {}; template<> struct priority_tag<0> {}; @@ -2237,16 +3299,32 @@ struct static_const template constexpr T static_const::value; + +} // namespace detail +} // namespace nlohmann + +// #include + + +namespace nlohmann +{ +namespace detail +{ +// dispatching helper struct +template struct identity_tag {}; } // namespace detail } // namespace nlohmann // #include -#include // not #include // numeric_limits #include // false_type, is_constructible, is_integral, is_same, true_type #include // declval +#include // tuple + +// #include + // #include @@ -2255,19 +3333,6 @@ constexpr T static_const::value; // #include - -namespace nlohmann -{ -namespace detail -{ -template struct make_void -{ - using type = void; -}; -template using void_t = typename make_void::type; -} // namespace detail -} // namespace nlohmann - // #include @@ -2275,10 +3340,10 @@ namespace nlohmann { namespace detail { -template +template struct iterator_types {}; -template +template struct iterator_types < It, void_t +template struct iterator_traits { }; -template +template struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> : iterator_types { }; -template +template struct iterator_traits::value>> { using iterator_category = std::random_access_iterator_tag; @@ -2316,70 +3381,31 @@ struct iterator_traits::value>> } // namespace detail } // namespace nlohmann -// #include - -// #include - -// #include - +// #include -#include -// #include +// #include -// http://en.cppreference.com/w/cpp/experimental/is_detected namespace nlohmann { -namespace detail -{ -struct nonesuch -{ - nonesuch() = delete; - ~nonesuch() = delete; - nonesuch(nonesuch const&) = delete; - nonesuch(nonesuch const&&) = delete; - void operator=(nonesuch const&) = delete; - void operator=(nonesuch&&) = delete; -}; - -template class Op, - class... Args> -struct detector -{ - using value_t = std::false_type; - using type = Default; -}; +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); +} // namespace nlohmann -template class Op, class... Args> -struct detector>, Op, Args...> -{ - using value_t = std::true_type; - using type = Op; -}; +// #include -template