ParameterIndexesTool.hh 5.1 KB
/*
 * ParameterIndexesTool.hh
 *
 *  Created on: Dec 10, 2014
 *      Author: AKKA
 */

#ifndef PARAMETERINDEXESTOOL_HH_
#define PARAMETERINDEXESTOOL_HH_

#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>

namespace AMDA {
namespace Common {

struct ParameterIndexComponent
{
public :
	ParameterIndexComponent(int dim1Index = -1, int dim2Index = -1) : _dim1Index(dim1Index), _dim2Index(dim2Index)
	{
	}

	int getDim1Index() const
	{
		return _dim1Index;
	}

	int getDim2Index() const
	{
		return _dim2Index;
	}

	bool isDefined()
	{
		return ((_dim1Index != -1) || (_dim2Index != -1));
	}

	/* operators */
	bool operator==(const ParameterIndexComponent& comp) const
	{
		return ((_dim1Index == comp._dim1Index) && (_dim2Index == comp._dim2Index));
	}

	bool operator!=(const ParameterIndexComponent& comp) const
	{
		return ((_dim1Index != comp._dim1Index) || (_dim2Index != comp._dim2Index));
	}

	bool operator<(const ParameterIndexComponent& comp) const
	{
		if (_dim1Index < comp._dim1Index)
			return true;
		if ((_dim1Index == comp._dim1Index) &&
			(_dim2Index < comp._dim2Index))
			return true;
		return false;
	}

	bool operator<=(const ParameterIndexComponent& comp) const
	{
		if (_dim1Index < comp._dim1Index)
			return true;
		if ((_dim1Index == comp._dim1Index) &&
			(_dim2Index <= comp._dim2Index))
			return true;
		return false;
	}

	bool operator>(const ParameterIndexComponent& comp) const
	{
		if (_dim1Index > comp._dim1Index)
			return true;
		if ((_dim1Index == comp._dim1Index) &&
			(_dim2Index > comp._dim2Index))
			return true;
		return false;
	}

	bool operator>=(const ParameterIndexComponent& comp) const
	{
		if (_dim1Index > comp._dim1Index)
			return true;
		if ((_dim1Index == comp._dim1Index) &&
			(_dim2Index >= comp._dim2Index))
			return true;
		return false;
	}

private :
	int _dim1Index;
	int _dim2Index;
};

typedef std::list<ParameterIndexComponent> ParameterIndexComponentList;

class ParameterIndexesTool {
public:
	ParameterIndexesTool(){}

	static bool parse(std::string indexesDef, int dim1Size, int dim2Size, ParameterIndexComponentList& indexList)
	{
		boost::algorithm::trim(indexesDef);

		if (indexesDef.empty())
		{
			if (dim2Size <= 0)
				indexesDef = "*";
			else
				indexesDef = "[*,*]";
		}

		//try to get single index definition
		int singleIndex;
		if (ParameterIndexesTool::getDimIndex(indexesDef, singleIndex))
		{
			if (singleIndex == -1)
			{
				for (int i = 0; i < dim1Size; ++i)
					indexList.push_back(ParameterIndexComponent(i));
			}
			else if ((singleIndex >= 0) && ((dim1Size == -1) || (singleIndex < dim1Size)))
				indexList.push_back(ParameterIndexComponent(singleIndex));
			else
				return false;

			return (!indexList.empty());
		}

		//try to get two dimensional index definition
		size_t pos = indexesDef.find("[");
		if (pos == std::string::npos)
			return false;

		if (indexesDef.find("]") == std::string::npos)
			return false;

		std::vector<std::string> indexes;
		std::string defPart = indexesDef.substr(1, indexesDef.length() - 2);
		boost::split(indexes, defPart, boost::is_any_of(","));
		if (indexes.size() != 2)
			return false;

		int dim1Index = -1;
		int dim2Index = -1;

		if (!getDimIndex(indexes[0], dim1Index) || !getDimIndex(indexes[1], dim2Index))
			return false;

		if (dim1Index == -1)
		{
			for (int i = 0; i < dim1Size; ++i)
			{
				if (dim2Index == -1)
				{
					for (int j = 0; j < dim2Size; ++j)
						indexList.push_back(ParameterIndexComponent(i,j));
				}
				else if ((dim2Index >= 0) && (dim2Index < dim2Size))
					indexList.push_back(ParameterIndexComponent(i,dim2Index));
				else
					return (!indexList.empty());
			}
		}
		else if ((dim1Index >= 0) || (dim1Index < dim1Size))
		{
			if (dim2Index == -1)
			{
				for (int j = 0; j < dim2Size; ++j)
					indexList.push_back(ParameterIndexComponent(dim1Index,j));
			}
			else if ((dim2Index >= 0) && ((dim2Size == -1) || (dim2Index < dim2Size)))
				indexList.push_back(ParameterIndexComponent(dim1Index,dim2Index));
			else
				return (!indexList.empty());
		}
		else
			return false;

		return true;
	}

	static int getRelatedDimForTab2D(std::string indexesDef)
	{
		boost::algorithm::trim(indexesDef);

		if (indexesDef.empty())
			return 0;

		size_t pos = indexesDef.find("[");
		if (pos == std::string::npos)
			return 0;

		if (indexesDef.find("]") == std::string::npos)
			return 0;

		std::vector<std::string> indexes;
		std::string defPart = indexesDef.substr(1, indexesDef.length() - 2);
		boost::split(indexes, defPart, boost::is_any_of(","));
		if (indexes.size() != 2)
			return 0;

		boost::algorithm::trim(indexes[0]);
		boost::algorithm::trim(indexes[1]);

		if ((indexes[0].compare("*") == 0) && (indexes[1].compare("*") != 0))
			return 0;

		if ((indexes[0].compare("*") != 0) && (indexes[1].compare("*") == 0))
			return 1;

		return 0;
	}
private:

	static bool getDimIndex(std::string dimDef, int& dimIndex)
	{
		dimIndex = -1;
		boost::algorithm::trim(dimDef);
		if (dimDef.compare("*") != 0)
		{
			try
			{
				dimIndex = boost::lexical_cast<int>(dimDef);
			}
			catch(boost::bad_lexical_cast& e)
			{
				return false;
			}
		}

		return true;
	}
};

} /* Common */
} /* AMDA */
#endif