file src/baseprinter.cpp
[No description available] More…
Namespaces
Name |
---|
Gambit TODO: see if we can use this one: |
Gambit::Printers Forward declaration. |
Defines
Name | |
---|---|
GETTYPEID(r, data, i, elem) | |
PRINTTYPEID(r, data, elem) | |
TYPE_CASES(r, data, elem) |
Detailed Description
Author: Ben Farmer (benjamin.farmer@fysik.su.se)
Date: 2017 Feb
Definitions for certain baseprinter functions
Authors (add name and date if you modify):
Macros Documentation
define GETTYPEID
#define GETTYPEID(
r,
data,
i,
elem
)
template<> \
std::size_t getTypeID<elem>(void) {return i+1;}
Specialisations of type ID getters ID zero reserved for null ID
define PRINTTYPEID
#define PRINTTYPEID(
r,
data,
elem
)
std::cout << " Type: " << STRINGIFY(elem) << ", TypeID: " << getTypeID<elem>() << std::endl;
define TYPE_CASES
#define TYPE_CASES(
r,
data,
elem
)
if( get_type(in_label) == getTypeID<elem>()) \
{ \
elem buffer; \
valid = retrieve(buffer, in_label, rank, pointID); \
if(valid) \
{ \
printer.print(buffer, out_label, rank, pointID); \
} \
} else
Source code
// GAMBIT: Global and Modular BSM Inference Tool
// *********************************************
/// \file
///
/// Definitions for certain baseprinter functions
///
/// *********************************************
///
/// Authors (add name and date if you modify):
///
/// \author Ben Farmer
/// (benjamin.farmer@fysik.su.se)
/// \date 2017 Feb
///
/// *********************************************
// Gambit
#include "gambit/Printers/baseprinter.hpp"
#include "gambit/Utils/util_functions.hpp"
// Boost
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/for_each_i.hpp>
//#include <boost/preprocessor/punctuation/comma_if.hpp>
// Code!
namespace Gambit
{
namespace Printers
{
/// Specialisations of type ID getters
/// ID zero reserved for null ID
#define GETTYPEID(r,data,i,elem) \
template<> \
std::size_t getTypeID<elem>(void) {return i+1;}
BOOST_PP_SEQ_FOR_EACH_I(GETTYPEID, _, PRINTABLE_TYPES)
#undef GETTYPEID
/// For debugging; print to stdout all the typeIDs for all types.
void printAllTypeIDs(void)
{
std::cout << "Types known to getTypeID<T>() function:" << std::endl;
#define PRINTTYPEID(r,data,elem) \
std::cout << " Type: " << STRINGIFY(elem) << ", TypeID: " << getTypeID<elem>() << std::endl;
BOOST_PP_SEQ_FOR_EACH(PRINTTYPEID, _, PRINTABLE_TYPES)
#undef PRINTTYPEID
}
/// Retrieve and directly print data to new output
bool BaseReader::retrieve_and_print(const std::string& in_label, const std::string& out_label, BaseBasePrinter& printer, const uint rank, const ulong pointID)
{
/// First need to get the type data for 'in_label', then call appropriate retrieve and print functions.
/// I think there is no choice but to do this with a big switch.
/// Also need to check if the type matches what the printer expects, and decide what to do in case
/// of mismatch.
bool valid = false; // Switch to true if value is successfully retrieved for this point
#define TYPE_CASES(r,data,elem) \
if( get_type(in_label) == getTypeID<elem>()) \
{ \
elem buffer; \
valid = retrieve(buffer, in_label, rank, pointID); \
if(valid) \
{ \
printer.print(buffer, out_label, rank, pointID); \
} \
} else
BOOST_PP_SEQ_FOR_EACH(TYPE_CASES, _, PRINTABLE_TYPES)
#undef TYPE_CASES
{
std::ostringstream err;
err << "Did not recognise retrieved type for data label '"<<in_label<<"'! This may indicate a bug in the Reader class you are using, please report it.";
printer_error().raise(LOCAL_INFO,err.str());
}
return valid;
}
/// Helper function for the ModelParameters '_retrieve' functions
/// Parses a printer label and checks if it contains a single model parameter.
/// "out" is a memory location to store the parameter name, if found.
/// "labelroot" is a memory location to store the rest of the label (i.e. minus the parameter name)
bool parse_label_for_ModelParameters(const std::string& fulllabel, const std::string& modelname, std::string& out, std::string& labelroot, bool case_sensitive)
{
bool result = false;
std::istringstream iss(fulllabel);
std::string capability;
std::string rest;
iss >> capability;
iss >> rest;
if(!iss)
{
// Weren't two elements to the label, so this can't be a match
result = false; // failed to match
}
else
{
//capability is "#NormalDist_parameters", for example
capability.erase(0,1); // cut off the first character (hash, in all potentially matching cases)
if(Utils::startsWith(capability,modelname,case_sensitive))
{
// Cut off the modelname which matched
capability.erase(0,modelname.size());
if(Utils::startsWith(capability,"_parameters",case_sensitive))
{
// Still good so far, check 'rest', should be something like @NormalDist::primary_parameters::mu
rest.erase(0,1); // cut off the first character (@, in all potentially matching cases)
std::vector<str> split_rest = Utils::delimiterSplit(rest, "::");
if(Utils::iequals(split_rest[0],modelname,case_sensitive) and split_rest.size()==3)
{
// Ok! We have a match!
out = split_rest[2];
result = true;
// Get the rest of the full label
labelroot = fulllabel;
// Erase the "::parameter_name" part
labelroot.erase(fulllabel.size() - out.size() - 2, out.size()+2);
} else { result = false; }
} else { result = false; }
} else { result = false; }
}
return result;
}
/// Helper function for the Spectrum '_retrieve' functions
/// Parses a printer label and checks if it contains a single Spectrum entry.
/// "out" is a memory location to store the spectrum entry name, if found.
/// "labelroot" is a memory location to store the rest of the label (i.e. minus the entry name)
// example label:
// #MSSM_spectrum @SpecBit::get_MSSM_spectrum_as_map::~u_(6,6) Pole_Mixing
bool parse_label_for_spectrum_entry(const std::string& fulllabel, const std::string& req_capability, const std::string& req_module, const std::string& req_function, std::string& outname, std::string& outtag, std::string& labelroot, bool case_sensitive)
{
bool result = false;
std::istringstream iss(fulllabel);
std::string capability;
std::string rest;
iss >> capability;
iss >> rest;
iss >> outtag; // Last element is that spectrum 'tag', e.g. dimensionless, Pole_Mixing, etc.
if(!iss)
{
// Weren't three elements to the label, so this can't be a match
result = false; // failed to match
}
else
{
//capability is "#MSSM_spectrum", for example
capability.erase(0,1); // cut off the first character (hash, in all potentially matching cases)
if(Utils::iequals(capability,req_capability,case_sensitive))
{
// Check 'rest', should be something like @SpecBit::get_MSSM_spectrum_as_map::~u_(6,6)
rest.erase(0,1); // cut off the first character (@, in all potentially matching cases)
std::vector<str> split_rest = Utils::delimiterSplit(rest, "::");
if( Utils::iequals(split_rest[0],req_module,case_sensitive)
and Utils::iequals(split_rest[1],req_function,case_sensitive)
and split_rest.size()==3)
{
// Ok! We have a match!
outname = split_rest[2];
result = true;
// Get the rest of the full label
labelroot = fulllabel;
// Erase the "::entryname tag" part
std::size_t offset = outname.size() + outtag.size() + 3; // Names plus :: plus space
labelroot.erase(fulllabel.size() - offset, offset);
} else { result = false; }
} else { result = false; }
}
return result;
}
}
}
Updated on 2024-07-18 at 13:53:33 +0000