9196fbfe5e
sim/param.hh: Add "template<>" to explicit template specialization. --HG-- extra : convert_revision : 05e2f4ad8141a8782fe09a0b6824baf56c9fc957
788 lines
23 KiB
C++
788 lines
23 KiB
C++
/*
|
|
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met: redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer;
|
|
* redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution;
|
|
* neither the name of the copyright holders nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef __SIM_PARAM_HH__
|
|
#define __SIM_PARAM_HH__
|
|
|
|
#include <iostream>
|
|
#include <list>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "sim/configfile.hh"
|
|
#include "sim/startup.hh"
|
|
|
|
// forward decls
|
|
class BaseParam;
|
|
class SimObject;
|
|
|
|
//
|
|
// The context of a parameter definition... usually a subclass of
|
|
// SimObjectBuilder (which derives from ParamContext), but abstracted
|
|
// here to support more global simulator control parameters as well.
|
|
//
|
|
class ParamContext : protected StartupCallback
|
|
{
|
|
private:
|
|
|
|
// static list of all ParamContext objects, built as a side effect
|
|
// of the ParamContext constructor
|
|
static std::list<ParamContext *> *ctxList;
|
|
|
|
protected:
|
|
|
|
// .ini file (database) for parameter lookup... initialized on call
|
|
// to parseParams()
|
|
IniFile *iniFilePtr;
|
|
|
|
// .ini file section for parameter lookup
|
|
const std::string iniSection;
|
|
|
|
typedef std::vector<BaseParam *> ParamList;
|
|
|
|
// list of parameters defined in this context
|
|
ParamList *paramList;
|
|
|
|
ParamList *getParamList() {
|
|
if (!paramList)
|
|
paramList = new ParamList;
|
|
return paramList;
|
|
}
|
|
|
|
public:
|
|
|
|
/// Initialization phases for ParamContext objects.
|
|
enum InitPhase {
|
|
NoAutoInit = -1, ///< Don't initialize at all... params
|
|
/// will be parsed later (used by
|
|
/// SimObjectBuilder, which parses
|
|
/// params in SimObject::create().
|
|
OutputInitPhase = 0, ///< Output stream initialization
|
|
TraceInitPhase = 1, ///< Trace context initialization:
|
|
/// depends on output streams, but
|
|
/// needs to come before others so we
|
|
/// can use tracing in other
|
|
/// ParamContext init code
|
|
StatsInitPhase = 2, ///< Stats output initialization
|
|
DefaultInitPhase = 3 ///< Everything else
|
|
};
|
|
|
|
/// Records the initialization phase for this ParamContext.
|
|
InitPhase initPhase;
|
|
|
|
/// Constructor.
|
|
/// @param _iniSection Name of .ini section corresponding to this context.
|
|
/// @param _initPhase Initialization phase (see InitPhase).
|
|
ParamContext(const std::string &_iniSection,
|
|
InitPhase _initPhase = DefaultInitPhase);
|
|
|
|
virtual ~ParamContext() {}
|
|
|
|
// add a parameter to the context... called from the parameter
|
|
// object's constructor (see BaseParam::BaseParam())
|
|
void addParam(BaseParam *);
|
|
|
|
// call parse() on all params in this context to convert string
|
|
// representations to parameter values
|
|
virtual void parseParams(IniFile &iniFile);
|
|
|
|
// Check parameter values for validity & consistency. Default
|
|
// implementation is no-op; derive subclass & override to add
|
|
// actual functionality here
|
|
virtual void checkParams();
|
|
|
|
// Clean up at end of execution: close file descriptors, etc.
|
|
// Default implementation is no-op; derive subclass & override to
|
|
// add actual functionality here
|
|
virtual void cleanup();
|
|
|
|
// dump parameter descriptions
|
|
void describeParams(std::ostream &);
|
|
|
|
// Display the parameters & values used
|
|
void showParams(std::ostream &);
|
|
|
|
// print context information for parameter error
|
|
virtual void printErrorProlog(std::ostream &);
|
|
|
|
// resolve a SimObject name in this context to an object pointer.
|
|
virtual SimObject *resolveSimObject(const std::string &name);
|
|
|
|
// generate the name for this instance of this context (used as a
|
|
// prefix to create unique names in resolveSimObject()
|
|
virtual const std::string &getInstanceName() { return iniSection; }
|
|
|
|
// return the configuration hierarchy node for this context. Bare
|
|
// ParamContext objects have no corresponding node, so the default
|
|
// implementation returns NULL.
|
|
virtual ConfigNode *getConfigNode() { return NULL; }
|
|
|
|
// Parse all parameters registered with all ParamContext objects.
|
|
static void parseAllContexts(IniFile &iniFile);
|
|
|
|
// Check all parameters registered with all ParamContext objects.
|
|
// (calls checkParams() on each)
|
|
static void checkAllContexts();
|
|
|
|
// Print all parameter values on indicated ostream.
|
|
static void showAllContexts(std::ostream &os);
|
|
|
|
// Clean up all registered ParamContext objects. (calls cleanup()
|
|
// on each)
|
|
static void cleanupAllContexts();
|
|
|
|
// print descriptions of all parameters registered with all
|
|
// ParamContext objects
|
|
static void describeAllContexts(std::ostream &os);
|
|
};
|
|
|
|
|
|
//
|
|
// Base class for all parameter objects
|
|
//
|
|
class BaseParam
|
|
{
|
|
public:
|
|
|
|
ParamContext *context;
|
|
std::string name;
|
|
std::string description; // text description for help message
|
|
bool wasSet; // true if parameter was set by user
|
|
bool hasDefault; // true if parameter has default value
|
|
|
|
BaseParam(ParamContext *_context, const std::string &_name,
|
|
const std::string &_description, bool _hasDefault)
|
|
: context(_context), name(_name), description(_description),
|
|
wasSet(false), hasDefault(_hasDefault)
|
|
{
|
|
context->addParam(this);
|
|
}
|
|
|
|
virtual ~BaseParam() {}
|
|
|
|
// a parameter is valid only if its value was set by the user or
|
|
// it has a default value
|
|
bool isValid() const
|
|
{
|
|
return (wasSet || hasDefault);
|
|
}
|
|
|
|
// set value by parsing string
|
|
virtual void parse(const std::string &s) = 0;
|
|
|
|
// display value to stream
|
|
virtual void showValue(std::ostream &) const = 0;
|
|
|
|
// display type to stream
|
|
virtual void showType(std::ostream &) const = 0;
|
|
|
|
// signal parse or usage error
|
|
virtual void die(const std::string &err) const;
|
|
};
|
|
|
|
//
|
|
// Template classes to specialize parameters to specific types.
|
|
//
|
|
// Param<T> is for single-valued (scalar) parameters of type T.
|
|
// VectorParam<T> is for multi-valued (vector) parameters of type T.
|
|
// These are specified in the .ini file as a space-delimited list of
|
|
// arguments.
|
|
//
|
|
template <class T>
|
|
class Param : public BaseParam
|
|
{
|
|
protected:
|
|
|
|
T value;
|
|
|
|
public:
|
|
|
|
// Param with default value: set value to default
|
|
Param(ParamContext *context,
|
|
const std::string &name, const std::string &description, T dfltValue)
|
|
: BaseParam(context, name, description, true),
|
|
value(dfltValue)
|
|
{
|
|
}
|
|
|
|
// Param with no default value: leave value uninitialized
|
|
Param(ParamContext *context,
|
|
const std::string &name, const std::string &description)
|
|
: BaseParam(context, name, description, false)
|
|
{
|
|
}
|
|
|
|
virtual ~Param() {}
|
|
|
|
operator T&()
|
|
{
|
|
// if we attempt to reference an invalid parameter (i.e., one
|
|
// with no default value that was not set by the user), die.
|
|
if (!isValid())
|
|
die("not found");
|
|
return value;
|
|
}
|
|
|
|
// display value to stream
|
|
virtual void showValue(std::ostream &os) const;
|
|
|
|
// display type to stream
|
|
virtual void showType(std::ostream &) const;
|
|
|
|
// set value by parsing string
|
|
virtual void parse(const std::string &s);
|
|
};
|
|
|
|
|
|
//
|
|
// Template class for vector-valued parameters (lists)
|
|
//
|
|
template <class T>
|
|
class VectorParam : public BaseParam
|
|
{
|
|
protected:
|
|
|
|
std::vector<T> value;
|
|
|
|
public:
|
|
|
|
typedef typename std::vector<T>::size_type size_type;
|
|
|
|
// Param with default value: set value to default
|
|
VectorParam(ParamContext *context, const std::string &name,
|
|
const std::string &description,
|
|
const std::vector<T> &dfltValue)
|
|
: BaseParam(context, name, description, true),
|
|
value(dfltValue)
|
|
{
|
|
}
|
|
|
|
// Param with no default value: leave value uninitialized
|
|
VectorParam(ParamContext *context,
|
|
const std::string &name, const std::string &description)
|
|
: BaseParam(context, name, description, false)
|
|
{
|
|
}
|
|
|
|
virtual ~VectorParam() {}
|
|
|
|
// basic vector access methods
|
|
size_type size() const
|
|
{
|
|
if (!isValid())
|
|
die("not found");
|
|
return value.size();
|
|
}
|
|
|
|
const T &operator[](size_type n) const
|
|
{
|
|
if (!isValid())
|
|
die("not found");
|
|
return value[n];
|
|
}
|
|
|
|
// return reference to value vector
|
|
operator std::vector<T>&()
|
|
{
|
|
if (!isValid())
|
|
die("not found");
|
|
return value;
|
|
}
|
|
|
|
// display value to stream
|
|
virtual void showValue(std::ostream &os) const;
|
|
|
|
// display type to stream
|
|
virtual void showType(std::ostream &) const;
|
|
|
|
// set value by parsing string
|
|
virtual void parse(const std::string &s);
|
|
};
|
|
|
|
//
|
|
// Specialization of Param<int> and VectorParam<int> to handle
|
|
// enumerated types is done in two ways, using SimpleEnumParam and
|
|
// MappedEnumParam (and their vector counterparts,
|
|
// SimpleEnumVectorParam and MappedEnumVectorParam). SimpleEnumParam
|
|
// takes an array of strings and maps them to integers based on array
|
|
// index. MappedEnumParam takes an array of string-to-int mappings,
|
|
// allowing for mapping strings to non-contiguous integer values, or
|
|
// mapping multiple strings to the same integer value.
|
|
//
|
|
// Both SimpleEnumParam and MappedEnumParam are implemented using a
|
|
// single template class, EnumParam<Map>, which takes the type of the map
|
|
// as a parameter (const char * or EnumParamMap). Similarly,
|
|
// SimpleEnumVectorParam and MappedEnumVectorParam are both
|
|
// implemented using EnumVectorParam<Map>.
|
|
//
|
|
template <class Map>
|
|
class EnumParam : public Param<int>
|
|
{
|
|
const int num_values;
|
|
const Map *map;
|
|
|
|
public:
|
|
|
|
// Param with default value: set value to default
|
|
EnumParam(ParamContext *context,
|
|
const std::string &name, const std::string &description,
|
|
const Map *_map, int _num_values,
|
|
int dfltValue)
|
|
: Param<int>(context, name, description, dfltValue),
|
|
num_values(_num_values), map(_map)
|
|
{
|
|
}
|
|
|
|
// Param with no default value: leave value uninitialized
|
|
EnumParam(ParamContext *context,
|
|
const std::string &name, const std::string &description,
|
|
const Map *_map, int _num_values)
|
|
: Param<int>(context, name, description),
|
|
num_values(_num_values), map(_map)
|
|
{
|
|
}
|
|
|
|
virtual ~EnumParam() {}
|
|
|
|
// display value to stream
|
|
virtual void showValue(std::ostream &os) const;
|
|
|
|
// display type to stream
|
|
virtual void showType(std::ostream &) const;
|
|
|
|
// set value by parsing string
|
|
virtual void parse(const std::string &s);
|
|
};
|
|
|
|
//
|
|
// Vector counterpart to SimpleEnumParam
|
|
//
|
|
template <class Map>
|
|
class EnumVectorParam : public VectorParam<int>
|
|
{
|
|
const int num_values;
|
|
const Map *map;
|
|
|
|
public:
|
|
|
|
// Param with default value: set value to default
|
|
EnumVectorParam(ParamContext *context,
|
|
const std::string &name, const std::string &description,
|
|
const Map *_map, int _num_values,
|
|
std::vector<int> &dfltValue)
|
|
: VectorParam<int>(context, name, description, dfltValue),
|
|
num_values(_num_values), map(_map)
|
|
{
|
|
}
|
|
|
|
// Param with no default value: leave value uninitialized
|
|
EnumVectorParam(ParamContext *context,
|
|
const std::string &name, const std::string &description,
|
|
const Map *_map, int _num_values)
|
|
: VectorParam<int>(context, name, description),
|
|
num_values(_num_values), map(_map)
|
|
{
|
|
}
|
|
|
|
virtual ~EnumVectorParam() {}
|
|
|
|
// display value to stream
|
|
virtual void showValue(std::ostream &os) const;
|
|
|
|
// display type to stream
|
|
virtual void showType(std::ostream &) const;
|
|
|
|
// set value by parsing string
|
|
virtual void parse(const std::string &s);
|
|
};
|
|
|
|
// Specialize EnumParam for a particular enumeration type ENUM
|
|
// (automates casting to get value of enum type)
|
|
|
|
template <class ENUM>
|
|
class SimpleEnumParam : public EnumParam<const char *>
|
|
{
|
|
public:
|
|
|
|
SimpleEnumParam(ParamContext *context,
|
|
const std::string &name, const std::string &description,
|
|
const char **_map, int _num_values,
|
|
ENUM dfltValue)
|
|
: EnumParam<const char *>(context, name, description,
|
|
_map, _num_values, (int)dfltValue)
|
|
{
|
|
}
|
|
|
|
SimpleEnumParam(ParamContext *context,
|
|
const std::string &name, const std::string &description,
|
|
const char **_map, int _num_values)
|
|
: EnumParam<const char *>(context, name, description,
|
|
_map, _num_values)
|
|
{
|
|
}
|
|
|
|
operator ENUM() const
|
|
{
|
|
if (!isValid())
|
|
die("not found");
|
|
return (ENUM)value;
|
|
}
|
|
};
|
|
|
|
|
|
// Specialize EnumParam for a particular enumeration type ENUM
|
|
// (automates casting to get value of enum type)
|
|
|
|
template <class ENUM>
|
|
class SimpleEnumVectorParam : public EnumVectorParam<const char *>
|
|
{
|
|
public:
|
|
|
|
// skip default value constructor: too much pain to convert
|
|
// vector<ENUM> initializer to vector<int>
|
|
|
|
|
|
SimpleEnumVectorParam(ParamContext *context,
|
|
const std::string &name,
|
|
const std::string &description,
|
|
const char **_map, int _num_values)
|
|
: EnumVectorParam<const char *>(context, name, description,
|
|
_map, _num_values)
|
|
{
|
|
}
|
|
|
|
ENUM operator[](size_type n)
|
|
{
|
|
if (!isValid())
|
|
die("not found");
|
|
return (ENUM)value[n];
|
|
}
|
|
};
|
|
|
|
|
|
//
|
|
// Handle enums via string-to-int map (see comment above).
|
|
//
|
|
|
|
// An array of string-to-int mappings must be supplied using the
|
|
// following type.
|
|
typedef struct {
|
|
const char *name;
|
|
int value;
|
|
} EnumParamMap;
|
|
|
|
// Specialize EnumParam for a particular enumeration type ENUM
|
|
// (automates casting to get value of enum type)
|
|
|
|
template <class ENUM>
|
|
class MappedEnumParam : public EnumParam<EnumParamMap>
|
|
{
|
|
public:
|
|
|
|
MappedEnumParam(ParamContext *context,
|
|
const std::string &name, const std::string &description,
|
|
const EnumParamMap *_map, int _num_values,
|
|
ENUM dfltValue)
|
|
: EnumParam<EnumParamMap>(context, name, description,
|
|
_map, _num_values, (int)dfltValue)
|
|
{
|
|
}
|
|
|
|
MappedEnumParam(ParamContext *context,
|
|
const std::string &name, const std::string &description,
|
|
const EnumParamMap *_map, int _num_values)
|
|
: EnumParam<EnumParamMap>(context, name, description,
|
|
_map, _num_values)
|
|
{
|
|
}
|
|
|
|
operator ENUM()
|
|
{
|
|
if (!isValid())
|
|
die("not found");
|
|
return (ENUM)value[this->n];
|
|
}
|
|
};
|
|
|
|
|
|
// Specialize EnumParam for a particular enumeration type ENUM
|
|
// (automates casting to get value of enum type)
|
|
|
|
template <class ENUM>
|
|
class MappedEnumVectorParam : public EnumVectorParam<EnumParamMap>
|
|
{
|
|
public:
|
|
|
|
// skip default value constructor: too much pain to convert
|
|
// vector<ENUM> initializer to vector<int>
|
|
|
|
|
|
MappedEnumVectorParam(ParamContext *context,
|
|
const std::string &name,
|
|
const std::string &description,
|
|
const EnumParamMap *_map, int _num_values)
|
|
: EnumVectorParam<EnumParamMap>(context, name, description,
|
|
_map, _num_values)
|
|
{
|
|
}
|
|
|
|
ENUM operator[](size_type n)
|
|
{
|
|
if (!isValid())
|
|
die("not found");
|
|
return (ENUM)value[n];
|
|
}
|
|
};
|
|
|
|
|
|
//
|
|
// Parameters that point to other simulation objects (e.g. caches,
|
|
// busses, etc.) are handled by specializing SimObjectBaseParam to the
|
|
// specific subtype. The main purpose of SimObjectBaseParam is to
|
|
// provide a place to stick several helper functions common to all
|
|
// SimObject-derived parameters.
|
|
//
|
|
class SimObjectBaseParam : public BaseParam
|
|
{
|
|
public:
|
|
|
|
SimObjectBaseParam(ParamContext *context, const std::string &name,
|
|
const std::string &description, bool hasDefault)
|
|
: BaseParam(context, name, description, hasDefault)
|
|
{
|
|
}
|
|
|
|
virtual ~SimObjectBaseParam() {}
|
|
|
|
// helper function for SimObjectParam<T>::showValue()
|
|
void showValue(std::ostream &os, SimObject *obj) const;
|
|
|
|
// helper function for SimObjectParam<T>::parse()
|
|
void parse(const std::string &s, SimObject *&value);
|
|
|
|
// helper function for SimObjectParam<T>::parse()
|
|
void parse(const std::string &s, std::vector<SimObject *>&value_vec);
|
|
};
|
|
|
|
|
|
//
|
|
// Parameter to a specific type of SimObject. Note that T must be a
|
|
// pointer to a class derived from SimObject (e.g., <CPU *>).
|
|
//
|
|
|
|
template <class T> class SimObjectParam;
|
|
|
|
template <class T>
|
|
class SimObjectParam<T *> : public SimObjectBaseParam
|
|
{
|
|
protected:
|
|
|
|
T *value;
|
|
|
|
public:
|
|
|
|
// initialization w/o default
|
|
SimObjectParam(ParamContext *context,
|
|
const std::string &name, const std::string &description)
|
|
: SimObjectBaseParam(context, name, description, false)
|
|
{
|
|
}
|
|
|
|
// initialization wit=h default
|
|
SimObjectParam(ParamContext *context,
|
|
const std::string &name, const std::string &description,
|
|
T *dfltValue)
|
|
: SimObjectBaseParam(context, name, description, true),
|
|
value(dfltValue)
|
|
{
|
|
}
|
|
|
|
virtual ~SimObjectParam() {}
|
|
|
|
// convert to pointer
|
|
operator T*()
|
|
{
|
|
if (!isValid())
|
|
die("not found");
|
|
return value;
|
|
}
|
|
|
|
T *operator->() const
|
|
{
|
|
if (!isValid())
|
|
die("not found");
|
|
return value;
|
|
}
|
|
|
|
// display value to stream
|
|
virtual void showValue(std::ostream &os) const
|
|
{
|
|
SimObjectBaseParam::showValue(os, value);
|
|
}
|
|
|
|
// display type to stream: see REGISTER_SIM_OBJECT macro in
|
|
// sim_object.hh for declaration
|
|
virtual void showType(std::ostream &os) const;
|
|
|
|
// set value by parsing string
|
|
virtual void parse(const std::string &s)
|
|
{
|
|
SimObject *so_ptr;
|
|
// first parse to generic SimObject *
|
|
SimObjectBaseParam::parse(s, so_ptr);
|
|
// now dynamic_cast to specific derived type
|
|
value = dynamic_cast<T *>(so_ptr);
|
|
// check for failure of dynamic_cast
|
|
if (value == NULL && so_ptr != NULL)
|
|
die("not of appropriate type");
|
|
}
|
|
};
|
|
|
|
|
|
//
|
|
// Vector counterpart to SimObjectParam<T>
|
|
//
|
|
|
|
template <class T> class SimObjectVectorParam;
|
|
|
|
template <class T>
|
|
class SimObjectVectorParam<T *> : public SimObjectBaseParam
|
|
{
|
|
protected:
|
|
|
|
std::vector<T *> value;
|
|
|
|
public:
|
|
|
|
typedef typename std::vector<T *>::size_type size_type;
|
|
|
|
SimObjectVectorParam(ParamContext *context,
|
|
const std::string &name,
|
|
const std::string &description)
|
|
: SimObjectBaseParam(context, name, description, false)
|
|
{
|
|
}
|
|
|
|
SimObjectVectorParam(ParamContext *context,
|
|
const std::string &name,
|
|
const std::string &description,
|
|
std::vector<T *> dfltValue)
|
|
: SimObjectBaseParam(context, name, description, true),
|
|
value(dfltValue)
|
|
{
|
|
}
|
|
|
|
virtual ~SimObjectVectorParam() {}
|
|
|
|
// basic vector access methods
|
|
size_type size() const
|
|
{
|
|
if (!isValid())
|
|
die("not found");
|
|
return value.size();
|
|
}
|
|
|
|
T *&operator[](size_type n)
|
|
{
|
|
if (!isValid())
|
|
die("not found");
|
|
return value[n];
|
|
}
|
|
|
|
// return reference to value vector
|
|
operator std::vector<T *>&()
|
|
{
|
|
if (!isValid())
|
|
die("not found");
|
|
return value;
|
|
}
|
|
|
|
// display value to stream
|
|
virtual void showValue(std::ostream &os) const
|
|
{
|
|
for (int i = 0; i < value.size(); i++) {
|
|
if (i != 0)
|
|
os << " ";
|
|
SimObjectBaseParam::showValue(os, value[i]);
|
|
}
|
|
}
|
|
|
|
// display type to stream: see
|
|
virtual void showType(std::ostream &os) const;
|
|
|
|
// set value by parsing string
|
|
virtual void parse(const std::string &s)
|
|
{
|
|
std::vector<SimObject *> so_ptr_vec;
|
|
// first parse to generic SimObject * vector (from SimObjectBaseParam)
|
|
SimObjectBaseParam::parse(s, so_ptr_vec);
|
|
|
|
value.resize(so_ptr_vec.size());
|
|
|
|
for (int i = 0; i < so_ptr_vec.size(); ++i) {
|
|
// now dynamic_cast to specific derived type
|
|
value[i] = dynamic_cast<T *>(so_ptr_vec[i]);
|
|
// check for failure of dynamic_cast
|
|
if (value[i] == NULL && so_ptr_vec[i] != NULL)
|
|
die("not of appropriate type");
|
|
}
|
|
}
|
|
};
|
|
|
|
//
|
|
// Macro to define showType() methods for SimObjectParam &
|
|
// SimObjectVectorParam. Can't do this automatically as it requires a
|
|
// string name for the type, which you can't get from a template
|
|
// argument. For concrete derived SimObject types, this macro is
|
|
// automatically invoked by REGISTER_SIM_OBJECT() (see sim_object.hh).
|
|
//
|
|
#define DEFINE_SIM_OBJECT_CLASS_NAME(CLASS_NAME, OBJ_CLASS) \
|
|
template<> \
|
|
void \
|
|
SimObjectParam<OBJ_CLASS *>::showType(std::ostream &os) const \
|
|
{ \
|
|
os << CLASS_NAME; \
|
|
} \
|
|
\
|
|
template<> \
|
|
void \
|
|
SimObjectVectorParam<OBJ_CLASS *>::showType(std::ostream &os) const \
|
|
{ \
|
|
os << "vector of " << CLASS_NAME; \
|
|
}
|
|
|
|
|
|
//
|
|
// Declarations for low-level parsing & displaying functions. These
|
|
// are used internally, but should not be used directly by clients of
|
|
// the parameter mechanism, but are declared here so they can be
|
|
// shared with the serialization code (see sim/serialize.cc).
|
|
template <class T> bool parseParam(const std::string &str, T &data);
|
|
template <class T> void showParam(std::ostream &os, const T &data);
|
|
|
|
#endif // _SIM_PARAM_HH_
|