/** This file is part of MAUS: http://micewww.pp.rl.ac.uk/projects/maus * * MAUS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MAUS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MAUS. If not, see . * */ #ifndef _SRC_LEGACY_INTERFACE_STLUTILS_HH_ #define _SRC_LEGACY_INTERFACE_STLUTILS_HH_ #include #include #include #include #include "Utils/Exception.hh" /** STLUtils namespace contains useful utility functions for the STL. * * There are a few things one would like to do for Standard Template Library * (STL) objects - for example, equality tests on STL containers, nicely * formatted print function for STL containers, etc. They're defined here. */ namespace STLUtils { /** Return a == b if a and b are same size and a[i] == b[i] for all i. * * The following operations must be defined for TEMP_ITER it: * - ++it prefix increment operator * - (*it) (that is unary *, i.e. dereference operator) * - it1 != it2 not equals operator * - (*it1) != (*it2) not equals operator of dereferenced object * * Call like e.g. \n * std::vector a,b;\n * bool test_equal = IterableEquality(a.begin(), a.end(), b.begin(), * b.end());\n * * Can give a segmentation fault if a.begin() is not between a.begin() and * a.end() (inclusive) */ template bool IterableEquality(TEMP_ITER a_begin, TEMP_ITER a_end, TEMP_ITER b_begin, TEMP_ITER b_end); /** Return a == b if a and b are same size and a[i] == b[i] for all i. * * This should work for STL containers of c-type objects. If you want to use * this function for STL containers of custom objects, you will need to define * != operator for your custom object. If you want to use this function for * custom containers of custom objects, you will need to define all of the * functions described here. * * Call like e.g. \n * std::vector a,b;\n * bool test_equal = IterableEquality(a, b);\n * * Specifically, the following operations must be defined for TEMP_CLASS c: * - c.begin() which returns an iterator object, here denoted as type * TEMP_ITER * - c.end() which returns an iterator object, here denoted as type * TEMP_ITER * * The following operations must be defined for container iterator TEMP_ITER * it: * - ++it prefix increment operator * - (*it) (that is unary *, i.e. dereference operator) that returns the * contained object, here denoted as TEMP_OBJ * - it1 != it2 not equals operator * * The following operations must be defined for contained object TEMP_OBJ obj: * - obj != obj not equals operator of dereferenced object */ template inline bool IterableEquality(const TEMP_CLASS& a, const TEMP_CLASS& b); /** Convert value to a std::string. * * Convert from Temp type to a string type. If the Temp type is a floating * point then precision sets the std::precision that will be used in the * conversion. * * The following operations must be defined for TEMP_CLASS * - std::ostream& operator<<(Temp, std::ostream&) */ template std::string ToStringP(TEMP_CLASS value, int precision); /** Convert value to a std::string. * Convert from Temp type to a string type. * * The following operations must be defined for TEMP_CLASS * - std::ostream& operator<<(Temp, std::ostream&) */ template std::string ToString(TEMP_CLASS value); /** Convert value from a std::string. * * Convert from string type to Template type. * * The following operations must be defined for TEMP_CLASS * - std::istream& operator>>(Temp, std::istream&) * Throws a MAUS::Exception if the conversion fails */ template TEMP_CLASS FromString(std::string value); /** Find and replace environment variables in a string * * Search through a string looking for environment variables with format like * "my_${ENV_VARIABLE}_string". Replace the ${ENV_VARIABLE} with the value of * the environment variable. Throw a Exception if the environment variable could * not be found. */ std::string ReplaceVariables(std::string fileName); } // STLUtils namespace end // Function definitions for inline and templates namespace STLUtils { template bool IterableEquality(const TEMP_CLASS& a, const TEMP_CLASS& b) { return IterableEquality(a.begin(), a.end(), b.begin(), b.end()); } template bool IterableEquality(TEMP_ITER a_begin, TEMP_ITER a_end, TEMP_ITER b_begin, TEMP_ITER b_end) { TEMP_ITER a_it = a_begin; TEMP_ITER b_it = b_begin; while (a_it != a_end && b_it != b_end) { if (*a_it != *b_it) return false; ++a_it; ++b_it; } if ( a_it != a_end || b_it != b_end ) return false; return true; } template std::string ToStringP (TEMP_CLASS value, int precision) { std::stringstream ss; ss << std::setprecision(precision); ss << value; return ss.str(); } template std::string ToString (TEMP_CLASS value) { std::stringstream ss; ss << value; return ss.str(); } template TEMP_CLASS FromString(std::string value) { std::stringstream ss(value); TEMP_CLASS out; ss >> out; if (ss.fail()) { throw MAUS::Exception(MAUS::Exception::recoverable, "Failed to parse "+value, "STLUtils::FromString(...)"); } return out; } } /** A macro to disallow the copy constructor and operator= functions * * The idea is that most classes don't want copy ctor and assignment * operator - by making them private we force the compiler to try to link * against the private function - which fails. This should be used in the * private: declarations for all classes wher copy constructor and assignment * operator are not defined. * * Summary - put this in private: declaration for all classes like * #include "Interface/include/STLUtils.hh" * class Foo { * public: * Foo(); * ~Foo(); * private: * DISALLOW_COPY_AND_ASSIGN(Foo); * }; */ #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&); \ void operator=(const TypeName&) #endif