mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-19 21:32:58 -04:00
263 lines
9.0 KiB
C++
263 lines
9.0 KiB
C++
// Filename: cppTemplateParameterList.cxx
|
|
// Created by: drose (28Oct99)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
//
|
|
// All use of this software is subject to the terms of the revised BSD
|
|
// license. You should have received a copy of this license along
|
|
// with this source code in a file named "LICENSE."
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#include "cppTemplateParameterList.h"
|
|
#include "cppClassTemplateParameter.h"
|
|
#include "cppInstance.h"
|
|
#include "cppExpression.h"
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPTemplateParameterList::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
CPPTemplateParameterList::
|
|
CPPTemplateParameterList() {
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPTemplateParameterList::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
string CPPTemplateParameterList::
|
|
get_string() const {
|
|
ostringstream strname;
|
|
strname << "< " << *this << " >";
|
|
return strname.str();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPTemplateParameterList::build_subst_decl
|
|
// Access: Public
|
|
// Description: Matches up the actual parameters one-to-one with the
|
|
// formal parameters they are replacing, so the template
|
|
// may be instantiated by swapping out each occurrence
|
|
// of a template standin type with its appropriate
|
|
// replacement.
|
|
////////////////////////////////////////////////////////////////////
|
|
void CPPTemplateParameterList::
|
|
build_subst_decl(const CPPTemplateParameterList &formal_params,
|
|
CPPDeclaration::SubstDecl &subst,
|
|
CPPScope *current_scope, CPPScope *global_scope) const {
|
|
Parameters::const_iterator pfi, pai;
|
|
for (pfi = formal_params._parameters.begin(), pai = _parameters.begin();
|
|
pfi != formal_params._parameters.end() && pai != _parameters.end();
|
|
++pfi, ++pai) {
|
|
CPPDeclaration *formal = *pfi;
|
|
CPPDeclaration *actual = *pai;
|
|
|
|
if (actual->as_type()) {
|
|
actual = actual->as_type()->resolve_type(current_scope, global_scope);
|
|
}
|
|
|
|
if (!(formal == actual)) {
|
|
subst.insert(CPPDeclaration::SubstDecl::value_type(formal, actual));
|
|
}
|
|
}
|
|
|
|
// Fill in the default template parameters.
|
|
while (pfi != formal_params._parameters.end()) {
|
|
CPPDeclaration *decl = (*pfi);
|
|
if (decl->as_instance()) {
|
|
// A value template parameter. Its default is an expression.
|
|
CPPInstance *inst = decl->as_instance();
|
|
if (inst->_initializer != NULL) {
|
|
CPPDeclaration *decl =
|
|
inst->_initializer->substitute_decl(subst, current_scope,
|
|
global_scope);
|
|
if (!(*decl == *inst)) {
|
|
subst.insert(CPPDeclaration::SubstDecl::value_type
|
|
(inst, decl));
|
|
}
|
|
}
|
|
} else if (decl->as_class_template_parameter()) {
|
|
// A class template parameter.
|
|
CPPClassTemplateParameter *cparam = decl->as_class_template_parameter();
|
|
if (cparam->_default_type != NULL) {
|
|
CPPDeclaration *decl =
|
|
cparam->_default_type->substitute_decl(subst, current_scope,
|
|
global_scope);
|
|
if (!(*cparam == *decl)) {
|
|
subst.insert(CPPDeclaration::SubstDecl::value_type
|
|
(cparam, decl));
|
|
}
|
|
}
|
|
}
|
|
++pfi;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPTemplateParameterList::is_fully_specified
|
|
// Access: Public
|
|
// Description: This function returns true if all the parameters in
|
|
// the list are real expressions or classes, and not
|
|
// types yet to-be-determined or template parameter
|
|
// types. That is, this returns true for a normal
|
|
// template instantiation, and false for a template
|
|
// instantiation based on template parameters that have
|
|
// not yet been specified.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool CPPTemplateParameterList::
|
|
is_fully_specified() const {
|
|
for (int i = 0; i < (int)_parameters.size(); ++i) {
|
|
if (!_parameters[i]->is_fully_specified()) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPTemplateParameterList::is_tbd
|
|
// Access: Public
|
|
// Description: Returns true if any type within the parameter list is
|
|
// a CPPTBDType and thus isn't fully determined right
|
|
// now.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool CPPTemplateParameterList::
|
|
is_tbd() const {
|
|
for (int i = 0; i < (int)_parameters.size(); ++i) {
|
|
CPPType *type = _parameters[i]->as_type();
|
|
if (type != (CPPType *)NULL &&
|
|
(type->is_tbd() || type->as_class_template_parameter() != NULL)) {
|
|
return true;
|
|
}
|
|
CPPExpression *expr = _parameters[i]->as_expression();
|
|
if (expr != NULL && expr->is_tbd()) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPTemplateParameterList::Equivalence Operator
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
bool CPPTemplateParameterList::
|
|
operator == (const CPPTemplateParameterList &other) const {
|
|
if (_parameters.size() != other._parameters.size()) {
|
|
return false;
|
|
}
|
|
for (int i = 0; i < (int)_parameters.size(); ++i) {
|
|
if (*_parameters[i] != *other._parameters[i]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPTemplateParameterList::Nonequivalence Operator
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
bool CPPTemplateParameterList::
|
|
operator != (const CPPTemplateParameterList &other) const {
|
|
return !(*this == other);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPTemplateParameterList::Ordering Operator
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
bool CPPTemplateParameterList::
|
|
operator < (const CPPTemplateParameterList &other) const {
|
|
if (_parameters.size() != other._parameters.size()) {
|
|
return _parameters.size() < other._parameters.size();
|
|
}
|
|
for (int i = 0; i < (int)_parameters.size(); ++i) {
|
|
if (*_parameters[i] != *other._parameters[i]) {
|
|
return *_parameters[i] < *other._parameters[i];
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPTemplateParameterList::substitute_decl
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
CPPTemplateParameterList *CPPTemplateParameterList::
|
|
substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|
CPPScope *current_scope, CPPScope *global_scope) {
|
|
CPPTemplateParameterList *rep = new CPPTemplateParameterList(*this);
|
|
|
|
bool anything_changed = false;
|
|
for (int i = 0; i < (int)rep->_parameters.size(); ++i) {
|
|
rep->_parameters[i] =
|
|
_parameters[i]->substitute_decl(subst, current_scope, global_scope);
|
|
if (rep->_parameters[i] != _parameters[i]) {
|
|
anything_changed = true;
|
|
}
|
|
}
|
|
|
|
if (!anything_changed) {
|
|
delete rep;
|
|
rep = this;
|
|
}
|
|
|
|
return rep;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPTemplateParameterList::output
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void CPPTemplateParameterList::
|
|
output(ostream &out, CPPScope *scope) const {
|
|
if (!_parameters.empty()) {
|
|
Parameters::const_iterator pi = _parameters.begin();
|
|
(*pi)->output(out, 0, scope, false);
|
|
|
|
++pi;
|
|
while (pi != _parameters.end()) {
|
|
out << ", ";
|
|
(*pi)->output(out, 0, scope, false);
|
|
++pi;
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPTemplateParameterList::write_formal
|
|
// Access: Public
|
|
// Description: Writes the list as a set of formal parameters for a
|
|
// template scope. Includes the keyword "template" and
|
|
// the angle brackets, as well as the trailing newline.
|
|
////////////////////////////////////////////////////////////////////
|
|
void CPPTemplateParameterList::
|
|
write_formal(ostream &out, CPPScope *scope) const {
|
|
out << "template<";
|
|
if (!_parameters.empty()) {
|
|
Parameters::const_iterator pi = _parameters.begin();
|
|
(*pi)->output(out, 0, scope, true);
|
|
|
|
++pi;
|
|
while (pi != _parameters.end()) {
|
|
out << ", ";
|
|
(*pi)->output(out, 0, scope, true);
|
|
++pi;
|
|
}
|
|
}
|
|
out << ">\n";
|
|
}
|