Code:
#include "school.h"
// returns false if it's already in the list
bool CourseeMgr::AddCourse(const Course& c)
{
std::list<Course>::iterator it;
for(it = CourseList.begin(); it != CourseList.end(); it++)
{
if(*it == c)
return false;
}
CourseList.push_back(c);
return true;
}
bool CourseeMgr::AddCourse(std::string name, std::string num)
{
return AddCourse(Course(name, num));
}
void CourseeMgr::AddAssignment(Course* ptr, const Assignment& trav)
{
ptr->Assignments.push_back(trav);
}
void CourseeMgr::FindCourse(std::list<Course>& ls, const std::string str, unsigned int type)
{
std::list<Course>::const_iterator it;
for(it = CourseList.begin(); it != CourseList.end(); it++)
{
if(type & C_NAME)
{
if(FindWithoutCase(str, it->Name))
{
ls.push_back(*it);
continue;
}
}
if(type & C_NUMBER)
{
if(FindWithoutCase(str, it->Number))
{
ls.push_back(*it);
continue;
}
}
}
}
// returns the first course that matches the search criteria
Course* CourseeMgr::FindCourseUnique(std::string name)
{
std::list<Course>::iterator it;
for(it = CourseList.begin(); it != CourseList.end(); it++)
{
if(FindWithoutCase(name, it->Name))
return &(*it);
}
return 0;
}
void CourseeMgr::FindAssignments(std::list<Course>& ls_result, const std::string str, unsigned int type)
{
// iterate through all courses
std::list<Course>::iterator courses_it;
for(courses_it = CourseList.begin(); courses_it != CourseList.end(); courses_it++)
{
std::list<Assignment>& ref = courses_it->Assignments;
// iterate through all assignments
std::list<Assignment>::iterator trav_it;
for(trav_it = ref.begin(); trav_it != ref.end(); trav_it++)
{
if(type & C_ASSIGNMENT_TITLE)
{
if(FindWithoutCase(str, trav_it->Title))
{
ls_result.push_back(Course(courses_it->Name, courses_it->Number));
ls_result.back().Assignments.push_back(*trav_it);
continue;
}
}
// POSSIBLE CASES FOR C_ASSIGNMENT_NOTE
// - add assignment if greater than or equal to x ">=x"
// - add assignment if lesser then or equal to x "<=x"
// - add assignment if exactly equal to x "x"
// - add assignment if at +- 'y' of 'x' "x+-y"
if(type & C_ASSIGNMENT_NOTE)
{
CMP_FUNC cmp_func = FindCmpFunc(str);
if(cmp_func != 0)
{
if(cmp_func == NULL_FUNCTION)
{
int a = 0;
int b = 0;
EraseCharactersPM(a, b, str);
if(ComparePPE(trav_it->Note, a + b) && ComparePGE(trav_it->Note, a - b))
{
ls_result.push_back(Course(courses_it->Name, courses_it->Number));
ls_result.back().Assignments.push_back(*trav_it);
continue;
}
else continue;
}
else
{
int data = 0;
EraseCharacters(data, str);
if(cmp_func(trav_it->Note, data))
{
ls_result.push_back(Course(courses_it->Name, courses_it->Number));
ls_result.back().Assignments.push_back(*trav_it);
continue;
}
else continue;
}
}
}
} // for(trav_it..
} // for(courses_it..
}
CMP_FUNC CourseeMgr::FindCmpFunc(const std::string& criteria)
{
CMP_FUNC func = 0;
// check if ">=x"
boost::regex e_pge("^>=\\b[0-9]{1,2}\\b$");
if(boost::regex_match(criteria, e_pge))
func = ComparePGE;
// check if "<=x"
boost::regex e_ppe("^<=\\b[0-9]{1,2}\\b$");
if(boost::regex_match(criteria, e_ppe))
func = ComparePPE;
// check if "x"
boost::regex e_exact("^\\b[0-9]{1,2}\\b$");
if(boost::regex_match(criteria, e_exact))
func = CompareExact;
// check if "x+-y"
boost::regex e_pm("^\\b[0-9]{1,2}\\b\\+-\\b[0-9]{1,2}\\b$");
if(boost::regex_match(criteria, e_pm))
func = NULL_FUNCTION;
return func;
}
bool ComparePGE(int a, int b)
{
return a >= b;
}
bool ComparePPE(int a, int b)
{
return a <= b;
}
bool CompareExact(int a, int b)
{
return a == b;
}
bool NULL_FUNCTION(int, int)
{
return 0;
}
void CourseeMgr::EraseCharacters(int& data, const std::string& criteria)
{
std::string::const_iterator it;
for(it = criteria.begin(); it != criteria.end(); it++)
if(isdigit(*it))
break;
std::string clean;
clean.append(it, criteria.end());
std::stringstream ss;
ss << clean;
ss >> data;
}
// HACK !!
// Particular case ( x+-y )
void CourseeMgr::EraseCharactersPM(int& x, int& y, const std::string& criteria)
{
std::string::const_iterator it;
for(it = criteria.begin(); it != criteria.end(); it++)
if(*it == '+')
break;
std::string clean;
clean.append(criteria.begin(), it);
std::stringstream ss;
ss << clean;
ss >> x;
clean.clear();
clean.append(it + 2, criteria.end());
ss.clear();
ss << clean;
ss >> y;
}
// Get rid of the dot which will mess with the regex query
void CourseeMgr::RemoveRegexCh(std::string& query)
{
const char* backslash = "\\";
for(int i = 0; i < query.size(); i++)
{
if(query[i] == '.')
query.insert(i++, backslash);
}
}
// returns true if 'research' is found inside element without
// consideration to case
bool CourseeMgr::FindWithoutCase(std::string research, std::string element)
{
RemoveRegexCh(research);
std::stringstream tmp;
tmp << ".*" << research << ".*";
boost::regex e(tmp.str(), boost::regex::icase);
return boost::regex_match(element, e, boost::match_default);
}
The red code is what I consider totally hack-ish.