Desináriza una cuadrícula linealizada en 2D y calcule la distancia entre 2 puntos -- ++ campo con performance campo con algorithm campo con array campo con coordinate-system camp codereview Relacionados El problema

De-linearize a 2d linearized grid and calculate distance between 2 points

3

problema

Español

En una simulación mía, para la cual el rendimiento es primordial, tengo el siguiente cuello de botella.

Tengo una enorme cuadrícula 2D de dimensiones  #include "awesome_ini.h" /* AUTHOR: Andrew McRobb DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 Copyright (C) 2015 Andrew McRobb <andrewmcrobb@gmail.com> Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. You just DO WHAT THE FUCK YOU WANT TO. */ awesome_ini::awesome_ini(std::string filename) { m_error = AWESOME_ERROR_NONE; m_error_line = 0; std::ifstream myfile (filename); if (!myfile.is_open()) { m_error = AWESOME_ERROR_FILE_PATH; return; } std::string line; size_t lineNumber = 1; size_t curGroup = 0; while ( getline (myfile,line) ) { line = trim(line); if(line.size() < 1){ continue; } /* IS IT A NEW GROUP? */ if(line[0] == '['){ std::size_t endi = line.find_last_of(']'); if(endi == std::string::npos){ m_error = AWESOME_ERROR_PARSING_INVALID_LINE; m_error_line = lineNumber; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } std::string cat = aw_strToLower(line.substr(1, (endi-1))); if(findDuplicateGroupName(cat)){ m_error = AWESOME_ERROR_DUBLICATED_GROUP_NAME; m_error_line = lineNumber; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } awesome_key_groups newGroup; newGroup.m_name = cat; m_list.push_back(newGroup); curGroup++; lineNumber++; continue; } std::size_t deli = line.find(AWI_SEPERATOR_CHAR); if(deli == std::string::npos){ m_error_line = lineNumber; m_error = AWESOME_ERROR_PARSING_INVALID_SEPERATOR_POS; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } if(curGroup == 0){ m_error_line = lineNumber; m_error = AWESOME_ERROR_NO_GROUP_DEFINED; break; } //Get the key and value... std::string key; std::string val; key = aw_strToLower(line.substr(0,deli)); val = line.substr(deli+1); /* CHECK THE KEY IS VALID */ if(!isNameValid(key)){ m_error_line = lineNumber; m_error = AWESOME_ERROR_PARSING_INVALID_NAME; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } /* ENSURE THE NAME IS ALREADY TAKEN! */ if(findDuplicateKeyName((curGroup-1), key)) { m_error_line = lineNumber; m_error = AWESOME_ERROR_DUPLICATED_KEY; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } awesome_key_element newKey; newKey.m_key = aw_strToLower(key); newKey.m_value = val; newKey.key_type = figureType(val); m_list.at((curGroup-1)).m_elements.push_back(newKey); lineNumber++; } myfile.close(); } AWESOME_INI_KEY_TYPE awesome_ini::figureType(std::string val){ //Is number? size_t string_length = val.length(); val = aw_strToLower(val); /* IS IT A BOOL? */ if(string_length <= 5) { if(val.compare("true") == 0 || val.compare("false") == 0) { return AWESOME_TYPE_BOOL; } } //Is it a stirng? for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(isalpha(c) && (c < 48 || c > 57)) { return AWESOME_TYPE_STRING; } } bool isInt = true; for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(c == ''){ break; } if(c < 48|| c > 57) { isInt = false; break; } } if(isInt){ return AWESOME_TYPE_INT; } bool isFloat = true; for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(c == ''){ break; } if((c < 48|| c > 57) && c != 46) { isFloat = false; break; } } if(isFloat){ return AWESOME_TYPE_FLOAT; } return AWESOME_TYPE_VOID; } bool awesome_ini::throwError(AWESOME_ERROR_CODES error) { m_error = error; bool quit = false; if (AWI_REMOVE_DATA_ON_ERROR) { clearAll(); quit = true; } return quit; } //Does the key include characters not allowed? bool awesome_ini::isNameValid(std::string line) { size_t length = line.size(); for (size_t i = 0; i < length; i++) { unsigned char c = line[i]; if (!isalpha(c) && c != '_') { return false; } } return true; } awesome_ini::~awesome_ini() { clearAll(); } std::string awesome_ini::trim(std::string line) { size_t length = line.size(); if(length == 0) { return ""; } //Look for comments and strip them! std::size_t comindex = line.find(AWI_COMMENT_CHAR); if(comindex != std::string::npos){ line = line.substr(0, comindex); if(line.size() == 0){ return ""; } } bool ignoreSpaces = false; std::string destBuffer = ""; for (size_t i = 0; i < length; i++) { char c = line[i]; if(c == AWI_STRING_CHAR && !ignoreSpaces){ ignoreSpaces = true; continue; } if(c == AWI_STRING_CHAR && ignoreSpaces){ if(i > 1){ if(line[i-1] == '\'){ destBuffer += c; continue; } } ignoreSpaces = false; continue; } if ((c == ' ' || c == ' ' || c == ' ' || c == ' ') && !ignoreSpaces) { continue; } destBuffer += c; } return destBuffer; } std::string awesome_ini::aw_strToLower(std::string line) { size_t length = line.size(); if(length == 0) { return ""; } std::string dstBuffer; for (size_t i = 0; i < length; i++) { if(line[i]<='Z' && line[i]>='A') { char c = line[i]; dstBuffer += c-('Z'-'z'); continue; } dstBuffer += line[i]; } return dstBuffer; } AWESOME_ERROR_CODES awesome_ini::getError(void) { return m_error; } size_t awesome_ini::getErrorLine(void) { return m_error_line; } std::size_t awesome_ini::findGroup(std::string name) { size_t group_size = m_list.size(); if(group_size == 0){ return std::string::npos; } for(size_t i = 0; i<group_size; i++) { if(m_list.at(i).m_name.compare(name) == 0) { return i; } } return std::string::npos; } bool awesome_ini::findDuplicateGroupName(std::string name) { if(findGroup(name) != std::string::npos) { return true; } return false; } bool awesome_ini::findDuplicateKeyName(size_t group, std::string name) { size_t group_size = m_list.size(); if(group >= group_size){ return false; } size_t group_key_size = m_list.at(group).m_elements.size(); if(group_key_size == 0) { return false; } for(size_t i = 0; i<group_key_size; i++) { if(m_list.at(group).m_elements.at(i).m_key.compare(name) == 0){ return true; } } return false; } //delete all data! void awesome_ini::clearAll(void) { size_t group_size = m_list.size(); for(size_t i = 0; i<group_size; i++) { m_list.at(i).m_elements.clear(); } m_list.clear(); } //Gets key value. Returns data type void if nothing found and error. bool awesome_ini::getKeyType(AWESOME_INI_KEY_TYPE &type, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ type = m_list.at(group_index).m_elements.at(i).key_type; return true; } } return false; } //Gets key value. Returns data type void if nothing found and error. bool awesome_ini::getKeyType(AWESOME_INI_KEY_TYPE &type, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ type = m_list.at(group).m_elements.at(i).key_type; return true; } } return false; } bool awesome_ini::getKeyInt(int &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_INT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atoi(m_list.at(group_index).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyInt(int &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_INT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atoi(m_list.at(group).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyBool(bool &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } std::string buffer; for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_BOOL) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } buffer = m_list.at(group_index).m_elements.at(i).m_value; } } if(buffer.size() == 0){ m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } //Convert string to lowercase... buffer = aw_strToLower(buffer); p = false; if (buffer.compare("true") == 0) { p = true; } return true; } bool awesome_ini::getKeyBool(bool &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } std::string buffer; for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_BOOL) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } buffer = m_list.at(group).m_elements.at(i).m_value; } } if(buffer.size() == 0){ m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } //Convert string to lowercase... buffer = aw_strToLower(buffer); p = false; if (buffer.compare("true") == 0) { p = true; } return true; } bool awesome_ini::getKeyFloat(float &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_FLOAT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atof(m_list.at(group_index).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyFloat(float &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_FLOAT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atof(m_list.at(group).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyString(std::string &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_STRING) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = m_list.at(group_index).m_elements.at(i).m_value.c_str(); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyString(std::string &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_STRING) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = m_list.at(group).m_elements.at(i).m_value.c_str(); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } 0  #include "awesome_ini.h" /* AUTHOR: Andrew McRobb DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 Copyright (C) 2015 Andrew McRobb <andrewmcrobb@gmail.com> Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. You just DO WHAT THE FUCK YOU WANT TO. */ awesome_ini::awesome_ini(std::string filename) { m_error = AWESOME_ERROR_NONE; m_error_line = 0; std::ifstream myfile (filename); if (!myfile.is_open()) { m_error = AWESOME_ERROR_FILE_PATH; return; } std::string line; size_t lineNumber = 1; size_t curGroup = 0; while ( getline (myfile,line) ) { line = trim(line); if(line.size() < 1){ continue; } /* IS IT A NEW GROUP? */ if(line[0] == '['){ std::size_t endi = line.find_last_of(']'); if(endi == std::string::npos){ m_error = AWESOME_ERROR_PARSING_INVALID_LINE; m_error_line = lineNumber; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } std::string cat = aw_strToLower(line.substr(1, (endi-1))); if(findDuplicateGroupName(cat)){ m_error = AWESOME_ERROR_DUBLICATED_GROUP_NAME; m_error_line = lineNumber; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } awesome_key_groups newGroup; newGroup.m_name = cat; m_list.push_back(newGroup); curGroup++; lineNumber++; continue; } std::size_t deli = line.find(AWI_SEPERATOR_CHAR); if(deli == std::string::npos){ m_error_line = lineNumber; m_error = AWESOME_ERROR_PARSING_INVALID_SEPERATOR_POS; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } if(curGroup == 0){ m_error_line = lineNumber; m_error = AWESOME_ERROR_NO_GROUP_DEFINED; break; } //Get the key and value... std::string key; std::string val; key = aw_strToLower(line.substr(0,deli)); val = line.substr(deli+1); /* CHECK THE KEY IS VALID */ if(!isNameValid(key)){ m_error_line = lineNumber; m_error = AWESOME_ERROR_PARSING_INVALID_NAME; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } /* ENSURE THE NAME IS ALREADY TAKEN! */ if(findDuplicateKeyName((curGroup-1), key)) { m_error_line = lineNumber; m_error = AWESOME_ERROR_DUPLICATED_KEY; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } awesome_key_element newKey; newKey.m_key = aw_strToLower(key); newKey.m_value = val; newKey.key_type = figureType(val); m_list.at((curGroup-1)).m_elements.push_back(newKey); lineNumber++; } myfile.close(); } AWESOME_INI_KEY_TYPE awesome_ini::figureType(std::string val){ //Is number? size_t string_length = val.length(); val = aw_strToLower(val); /* IS IT A BOOL? */ if(string_length <= 5) { if(val.compare("true") == 0 || val.compare("false") == 0) { return AWESOME_TYPE_BOOL; } } //Is it a stirng? for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(isalpha(c) && (c < 48 || c > 57)) { return AWESOME_TYPE_STRING; } } bool isInt = true; for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(c == ''){ break; } if(c < 48|| c > 57) { isInt = false; break; } } if(isInt){ return AWESOME_TYPE_INT; } bool isFloat = true; for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(c == ''){ break; } if((c < 48|| c > 57) && c != 46) { isFloat = false; break; } } if(isFloat){ return AWESOME_TYPE_FLOAT; } return AWESOME_TYPE_VOID; } bool awesome_ini::throwError(AWESOME_ERROR_CODES error) { m_error = error; bool quit = false; if (AWI_REMOVE_DATA_ON_ERROR) { clearAll(); quit = true; } return quit; } //Does the key include characters not allowed? bool awesome_ini::isNameValid(std::string line) { size_t length = line.size(); for (size_t i = 0; i < length; i++) { unsigned char c = line[i]; if (!isalpha(c) && c != '_') { return false; } } return true; } awesome_ini::~awesome_ini() { clearAll(); } std::string awesome_ini::trim(std::string line) { size_t length = line.size(); if(length == 0) { return ""; } //Look for comments and strip them! std::size_t comindex = line.find(AWI_COMMENT_CHAR); if(comindex != std::string::npos){ line = line.substr(0, comindex); if(line.size() == 0){ return ""; } } bool ignoreSpaces = false; std::string destBuffer = ""; for (size_t i = 0; i < length; i++) { char c = line[i]; if(c == AWI_STRING_CHAR && !ignoreSpaces){ ignoreSpaces = true; continue; } if(c == AWI_STRING_CHAR && ignoreSpaces){ if(i > 1){ if(line[i-1] == '\'){ destBuffer += c; continue; } } ignoreSpaces = false; continue; } if ((c == ' ' || c == ' ' || c == ' ' || c == ' ') && !ignoreSpaces) { continue; } destBuffer += c; } return destBuffer; } std::string awesome_ini::aw_strToLower(std::string line) { size_t length = line.size(); if(length == 0) { return ""; } std::string dstBuffer; for (size_t i = 0; i < length; i++) { if(line[i]<='Z' && line[i]>='A') { char c = line[i]; dstBuffer += c-('Z'-'z'); continue; } dstBuffer += line[i]; } return dstBuffer; } AWESOME_ERROR_CODES awesome_ini::getError(void) { return m_error; } size_t awesome_ini::getErrorLine(void) { return m_error_line; } std::size_t awesome_ini::findGroup(std::string name) { size_t group_size = m_list.size(); if(group_size == 0){ return std::string::npos; } for(size_t i = 0; i<group_size; i++) { if(m_list.at(i).m_name.compare(name) == 0) { return i; } } return std::string::npos; } bool awesome_ini::findDuplicateGroupName(std::string name) { if(findGroup(name) != std::string::npos) { return true; } return false; } bool awesome_ini::findDuplicateKeyName(size_t group, std::string name) { size_t group_size = m_list.size(); if(group >= group_size){ return false; } size_t group_key_size = m_list.at(group).m_elements.size(); if(group_key_size == 0) { return false; } for(size_t i = 0; i<group_key_size; i++) { if(m_list.at(group).m_elements.at(i).m_key.compare(name) == 0){ return true; } } return false; } //delete all data! void awesome_ini::clearAll(void) { size_t group_size = m_list.size(); for(size_t i = 0; i<group_size; i++) { m_list.at(i).m_elements.clear(); } m_list.clear(); } //Gets key value. Returns data type void if nothing found and error. bool awesome_ini::getKeyType(AWESOME_INI_KEY_TYPE &type, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ type = m_list.at(group_index).m_elements.at(i).key_type; return true; } } return false; } //Gets key value. Returns data type void if nothing found and error. bool awesome_ini::getKeyType(AWESOME_INI_KEY_TYPE &type, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ type = m_list.at(group).m_elements.at(i).key_type; return true; } } return false; } bool awesome_ini::getKeyInt(int &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_INT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atoi(m_list.at(group_index).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyInt(int &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_INT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atoi(m_list.at(group).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyBool(bool &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } std::string buffer; for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_BOOL) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } buffer = m_list.at(group_index).m_elements.at(i).m_value; } } if(buffer.size() == 0){ m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } //Convert string to lowercase... buffer = aw_strToLower(buffer); p = false; if (buffer.compare("true") == 0) { p = true; } return true; } bool awesome_ini::getKeyBool(bool &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } std::string buffer; for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_BOOL) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } buffer = m_list.at(group).m_elements.at(i).m_value; } } if(buffer.size() == 0){ m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } //Convert string to lowercase... buffer = aw_strToLower(buffer); p = false; if (buffer.compare("true") == 0) { p = true; } return true; } bool awesome_ini::getKeyFloat(float &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_FLOAT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atof(m_list.at(group_index).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyFloat(float &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_FLOAT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atof(m_list.at(group).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyString(std::string &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_STRING) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = m_list.at(group_index).m_elements.at(i).m_value.c_str(); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyString(std::string &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_STRING) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = m_list.at(group).m_elements.at(i).m_value.c_str(); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } 1 , cuyas dimensiones se almacenan en forma linealizada, es decir, posiciones en #include "awesome_ini.h" /* AUTHOR: Andrew McRobb DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 Copyright (C) 2015 Andrew McRobb <andrewmcrobb@gmail.com> Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. You just DO WHAT THE FUCK YOU WANT TO. */ awesome_ini::awesome_ini(std::string filename) { m_error = AWESOME_ERROR_NONE; m_error_line = 0; std::ifstream myfile (filename); if (!myfile.is_open()) { m_error = AWESOME_ERROR_FILE_PATH; return; } std::string line; size_t lineNumber = 1; size_t curGroup = 0; while ( getline (myfile,line) ) { line = trim(line); if(line.size() < 1){ continue; } /* IS IT A NEW GROUP? */ if(line[0] == '['){ std::size_t endi = line.find_last_of(']'); if(endi == std::string::npos){ m_error = AWESOME_ERROR_PARSING_INVALID_LINE; m_error_line = lineNumber; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } std::string cat = aw_strToLower(line.substr(1, (endi-1))); if(findDuplicateGroupName(cat)){ m_error = AWESOME_ERROR_DUBLICATED_GROUP_NAME; m_error_line = lineNumber; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } awesome_key_groups newGroup; newGroup.m_name = cat; m_list.push_back(newGroup); curGroup++; lineNumber++; continue; } std::size_t deli = line.find(AWI_SEPERATOR_CHAR); if(deli == std::string::npos){ m_error_line = lineNumber; m_error = AWESOME_ERROR_PARSING_INVALID_SEPERATOR_POS; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } if(curGroup == 0){ m_error_line = lineNumber; m_error = AWESOME_ERROR_NO_GROUP_DEFINED; break; } //Get the key and value... std::string key; std::string val; key = aw_strToLower(line.substr(0,deli)); val = line.substr(deli+1); /* CHECK THE KEY IS VALID */ if(!isNameValid(key)){ m_error_line = lineNumber; m_error = AWESOME_ERROR_PARSING_INVALID_NAME; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } /* ENSURE THE NAME IS ALREADY TAKEN! */ if(findDuplicateKeyName((curGroup-1), key)) { m_error_line = lineNumber; m_error = AWESOME_ERROR_DUPLICATED_KEY; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } awesome_key_element newKey; newKey.m_key = aw_strToLower(key); newKey.m_value = val; newKey.key_type = figureType(val); m_list.at((curGroup-1)).m_elements.push_back(newKey); lineNumber++; } myfile.close(); } AWESOME_INI_KEY_TYPE awesome_ini::figureType(std::string val){ //Is number? size_t string_length = val.length(); val = aw_strToLower(val); /* IS IT A BOOL? */ if(string_length <= 5) { if(val.compare("true") == 0 || val.compare("false") == 0) { return AWESOME_TYPE_BOOL; } } //Is it a stirng? for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(isalpha(c) && (c < 48 || c > 57)) { return AWESOME_TYPE_STRING; } } bool isInt = true; for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(c == ''){ break; } if(c < 48|| c > 57) { isInt = false; break; } } if(isInt){ return AWESOME_TYPE_INT; } bool isFloat = true; for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(c == ''){ break; } if((c < 48|| c > 57) && c != 46) { isFloat = false; break; } } if(isFloat){ return AWESOME_TYPE_FLOAT; } return AWESOME_TYPE_VOID; } bool awesome_ini::throwError(AWESOME_ERROR_CODES error) { m_error = error; bool quit = false; if (AWI_REMOVE_DATA_ON_ERROR) { clearAll(); quit = true; } return quit; } //Does the key include characters not allowed? bool awesome_ini::isNameValid(std::string line) { size_t length = line.size(); for (size_t i = 0; i < length; i++) { unsigned char c = line[i]; if (!isalpha(c) && c != '_') { return false; } } return true; } awesome_ini::~awesome_ini() { clearAll(); } std::string awesome_ini::trim(std::string line) { size_t length = line.size(); if(length == 0) { return ""; } //Look for comments and strip them! std::size_t comindex = line.find(AWI_COMMENT_CHAR); if(comindex != std::string::npos){ line = line.substr(0, comindex); if(line.size() == 0){ return ""; } } bool ignoreSpaces = false; std::string destBuffer = ""; for (size_t i = 0; i < length; i++) { char c = line[i]; if(c == AWI_STRING_CHAR && !ignoreSpaces){ ignoreSpaces = true; continue; } if(c == AWI_STRING_CHAR && ignoreSpaces){ if(i > 1){ if(line[i-1] == '\'){ destBuffer += c; continue; } } ignoreSpaces = false; continue; } if ((c == ' ' || c == ' ' || c == ' ' || c == ' ') && !ignoreSpaces) { continue; } destBuffer += c; } return destBuffer; } std::string awesome_ini::aw_strToLower(std::string line) { size_t length = line.size(); if(length == 0) { return ""; } std::string dstBuffer; for (size_t i = 0; i < length; i++) { if(line[i]<='Z' && line[i]>='A') { char c = line[i]; dstBuffer += c-('Z'-'z'); continue; } dstBuffer += line[i]; } return dstBuffer; } AWESOME_ERROR_CODES awesome_ini::getError(void) { return m_error; } size_t awesome_ini::getErrorLine(void) { return m_error_line; } std::size_t awesome_ini::findGroup(std::string name) { size_t group_size = m_list.size(); if(group_size == 0){ return std::string::npos; } for(size_t i = 0; i<group_size; i++) { if(m_list.at(i).m_name.compare(name) == 0) { return i; } } return std::string::npos; } bool awesome_ini::findDuplicateGroupName(std::string name) { if(findGroup(name) != std::string::npos) { return true; } return false; } bool awesome_ini::findDuplicateKeyName(size_t group, std::string name) { size_t group_size = m_list.size(); if(group >= group_size){ return false; } size_t group_key_size = m_list.at(group).m_elements.size(); if(group_key_size == 0) { return false; } for(size_t i = 0; i<group_key_size; i++) { if(m_list.at(group).m_elements.at(i).m_key.compare(name) == 0){ return true; } } return false; } //delete all data! void awesome_ini::clearAll(void) { size_t group_size = m_list.size(); for(size_t i = 0; i<group_size; i++) { m_list.at(i).m_elements.clear(); } m_list.clear(); } //Gets key value. Returns data type void if nothing found and error. bool awesome_ini::getKeyType(AWESOME_INI_KEY_TYPE &type, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ type = m_list.at(group_index).m_elements.at(i).key_type; return true; } } return false; } //Gets key value. Returns data type void if nothing found and error. bool awesome_ini::getKeyType(AWESOME_INI_KEY_TYPE &type, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ type = m_list.at(group).m_elements.at(i).key_type; return true; } } return false; } bool awesome_ini::getKeyInt(int &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_INT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atoi(m_list.at(group_index).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyInt(int &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_INT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atoi(m_list.at(group).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyBool(bool &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } std::string buffer; for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_BOOL) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } buffer = m_list.at(group_index).m_elements.at(i).m_value; } } if(buffer.size() == 0){ m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } //Convert string to lowercase... buffer = aw_strToLower(buffer); p = false; if (buffer.compare("true") == 0) { p = true; } return true; } bool awesome_ini::getKeyBool(bool &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } std::string buffer; for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_BOOL) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } buffer = m_list.at(group).m_elements.at(i).m_value; } } if(buffer.size() == 0){ m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } //Convert string to lowercase... buffer = aw_strToLower(buffer); p = false; if (buffer.compare("true") == 0) { p = true; } return true; } bool awesome_ini::getKeyFloat(float &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_FLOAT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atof(m_list.at(group_index).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyFloat(float &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_FLOAT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atof(m_list.at(group).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyString(std::string &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_STRING) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = m_list.at(group_index).m_elements.at(i).m_value.c_str(); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyString(std::string &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_STRING) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = m_list.at(group).m_elements.at(i).m_value.c_str(); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } 2 y < Código> #include "awesome_ini.h" /* AUTHOR: Andrew McRobb DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 Copyright (C) 2015 Andrew McRobb <andrewmcrobb@gmail.com> Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. You just DO WHAT THE FUCK YOU WANT TO. */ awesome_ini::awesome_ini(std::string filename) { m_error = AWESOME_ERROR_NONE; m_error_line = 0; std::ifstream myfile (filename); if (!myfile.is_open()) { m_error = AWESOME_ERROR_FILE_PATH; return; } std::string line; size_t lineNumber = 1; size_t curGroup = 0; while ( getline (myfile,line) ) { line = trim(line); if(line.size() < 1){ continue; } /* IS IT A NEW GROUP? */ if(line[0] == '['){ std::size_t endi = line.find_last_of(']'); if(endi == std::string::npos){ m_error = AWESOME_ERROR_PARSING_INVALID_LINE; m_error_line = lineNumber; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } std::string cat = aw_strToLower(line.substr(1, (endi-1))); if(findDuplicateGroupName(cat)){ m_error = AWESOME_ERROR_DUBLICATED_GROUP_NAME; m_error_line = lineNumber; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } awesome_key_groups newGroup; newGroup.m_name = cat; m_list.push_back(newGroup); curGroup++; lineNumber++; continue; } std::size_t deli = line.find(AWI_SEPERATOR_CHAR); if(deli == std::string::npos){ m_error_line = lineNumber; m_error = AWESOME_ERROR_PARSING_INVALID_SEPERATOR_POS; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } if(curGroup == 0){ m_error_line = lineNumber; m_error = AWESOME_ERROR_NO_GROUP_DEFINED; break; } //Get the key and value... std::string key; std::string val; key = aw_strToLower(line.substr(0,deli)); val = line.substr(deli+1); /* CHECK THE KEY IS VALID */ if(!isNameValid(key)){ m_error_line = lineNumber; m_error = AWESOME_ERROR_PARSING_INVALID_NAME; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } /* ENSURE THE NAME IS ALREADY TAKEN! */ if(findDuplicateKeyName((curGroup-1), key)) { m_error_line = lineNumber; m_error = AWESOME_ERROR_DUPLICATED_KEY; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } awesome_key_element newKey; newKey.m_key = aw_strToLower(key); newKey.m_value = val; newKey.key_type = figureType(val); m_list.at((curGroup-1)).m_elements.push_back(newKey); lineNumber++; } myfile.close(); } AWESOME_INI_KEY_TYPE awesome_ini::figureType(std::string val){ //Is number? size_t string_length = val.length(); val = aw_strToLower(val); /* IS IT A BOOL? */ if(string_length <= 5) { if(val.compare("true") == 0 || val.compare("false") == 0) { return AWESOME_TYPE_BOOL; } } //Is it a stirng? for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(isalpha(c) && (c < 48 || c > 57)) { return AWESOME_TYPE_STRING; } } bool isInt = true; for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(c == ''){ break; } if(c < 48|| c > 57) { isInt = false; break; } } if(isInt){ return AWESOME_TYPE_INT; } bool isFloat = true; for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(c == ''){ break; } if((c < 48|| c > 57) && c != 46) { isFloat = false; break; } } if(isFloat){ return AWESOME_TYPE_FLOAT; } return AWESOME_TYPE_VOID; } bool awesome_ini::throwError(AWESOME_ERROR_CODES error) { m_error = error; bool quit = false; if (AWI_REMOVE_DATA_ON_ERROR) { clearAll(); quit = true; } return quit; } //Does the key include characters not allowed? bool awesome_ini::isNameValid(std::string line) { size_t length = line.size(); for (size_t i = 0; i < length; i++) { unsigned char c = line[i]; if (!isalpha(c) && c != '_') { return false; } } return true; } awesome_ini::~awesome_ini() { clearAll(); } std::string awesome_ini::trim(std::string line) { size_t length = line.size(); if(length == 0) { return ""; } //Look for comments and strip them! std::size_t comindex = line.find(AWI_COMMENT_CHAR); if(comindex != std::string::npos){ line = line.substr(0, comindex); if(line.size() == 0){ return ""; } } bool ignoreSpaces = false; std::string destBuffer = ""; for (size_t i = 0; i < length; i++) { char c = line[i]; if(c == AWI_STRING_CHAR && !ignoreSpaces){ ignoreSpaces = true; continue; } if(c == AWI_STRING_CHAR && ignoreSpaces){ if(i > 1){ if(line[i-1] == '\'){ destBuffer += c; continue; } } ignoreSpaces = false; continue; } if ((c == ' ' || c == ' ' || c == ' ' || c == ' ') && !ignoreSpaces) { continue; } destBuffer += c; } return destBuffer; } std::string awesome_ini::aw_strToLower(std::string line) { size_t length = line.size(); if(length == 0) { return ""; } std::string dstBuffer; for (size_t i = 0; i < length; i++) { if(line[i]<='Z' && line[i]>='A') { char c = line[i]; dstBuffer += c-('Z'-'z'); continue; } dstBuffer += line[i]; } return dstBuffer; } AWESOME_ERROR_CODES awesome_ini::getError(void) { return m_error; } size_t awesome_ini::getErrorLine(void) { return m_error_line; } std::size_t awesome_ini::findGroup(std::string name) { size_t group_size = m_list.size(); if(group_size == 0){ return std::string::npos; } for(size_t i = 0; i<group_size; i++) { if(m_list.at(i).m_name.compare(name) == 0) { return i; } } return std::string::npos; } bool awesome_ini::findDuplicateGroupName(std::string name) { if(findGroup(name) != std::string::npos) { return true; } return false; } bool awesome_ini::findDuplicateKeyName(size_t group, std::string name) { size_t group_size = m_list.size(); if(group >= group_size){ return false; } size_t group_key_size = m_list.at(group).m_elements.size(); if(group_key_size == 0) { return false; } for(size_t i = 0; i<group_key_size; i++) { if(m_list.at(group).m_elements.at(i).m_key.compare(name) == 0){ return true; } } return false; } //delete all data! void awesome_ini::clearAll(void) { size_t group_size = m_list.size(); for(size_t i = 0; i<group_size; i++) { m_list.at(i).m_elements.clear(); } m_list.clear(); } //Gets key value. Returns data type void if nothing found and error. bool awesome_ini::getKeyType(AWESOME_INI_KEY_TYPE &type, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ type = m_list.at(group_index).m_elements.at(i).key_type; return true; } } return false; } //Gets key value. Returns data type void if nothing found and error. bool awesome_ini::getKeyType(AWESOME_INI_KEY_TYPE &type, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ type = m_list.at(group).m_elements.at(i).key_type; return true; } } return false; } bool awesome_ini::getKeyInt(int &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_INT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atoi(m_list.at(group_index).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyInt(int &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_INT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atoi(m_list.at(group).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyBool(bool &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } std::string buffer; for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_BOOL) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } buffer = m_list.at(group_index).m_elements.at(i).m_value; } } if(buffer.size() == 0){ m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } //Convert string to lowercase... buffer = aw_strToLower(buffer); p = false; if (buffer.compare("true") == 0) { p = true; } return true; } bool awesome_ini::getKeyBool(bool &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } std::string buffer; for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_BOOL) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } buffer = m_list.at(group).m_elements.at(i).m_value; } } if(buffer.size() == 0){ m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } //Convert string to lowercase... buffer = aw_strToLower(buffer); p = false; if (buffer.compare("true") == 0) { p = true; } return true; } bool awesome_ini::getKeyFloat(float &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_FLOAT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atof(m_list.at(group_index).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyFloat(float &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_FLOAT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atof(m_list.at(group).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyString(std::string &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_STRING) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = m_list.at(group_index).m_elements.at(i).m_value.c_str(); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyString(std::string &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_STRING) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = m_list.at(group).m_elements.at(i).m_value.c_str(); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } 3 se almacenan como un entero  #include "awesome_ini.h" /* AUTHOR: Andrew McRobb DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 Copyright (C) 2015 Andrew McRobb <andrewmcrobb@gmail.com> Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. You just DO WHAT THE FUCK YOU WANT TO. */ awesome_ini::awesome_ini(std::string filename) { m_error = AWESOME_ERROR_NONE; m_error_line = 0; std::ifstream myfile (filename); if (!myfile.is_open()) { m_error = AWESOME_ERROR_FILE_PATH; return; } std::string line; size_t lineNumber = 1; size_t curGroup = 0; while ( getline (myfile,line) ) { line = trim(line); if(line.size() < 1){ continue; } /* IS IT A NEW GROUP? */ if(line[0] == '['){ std::size_t endi = line.find_last_of(']'); if(endi == std::string::npos){ m_error = AWESOME_ERROR_PARSING_INVALID_LINE; m_error_line = lineNumber; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } std::string cat = aw_strToLower(line.substr(1, (endi-1))); if(findDuplicateGroupName(cat)){ m_error = AWESOME_ERROR_DUBLICATED_GROUP_NAME; m_error_line = lineNumber; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } awesome_key_groups newGroup; newGroup.m_name = cat; m_list.push_back(newGroup); curGroup++; lineNumber++; continue; } std::size_t deli = line.find(AWI_SEPERATOR_CHAR); if(deli == std::string::npos){ m_error_line = lineNumber; m_error = AWESOME_ERROR_PARSING_INVALID_SEPERATOR_POS; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } if(curGroup == 0){ m_error_line = lineNumber; m_error = AWESOME_ERROR_NO_GROUP_DEFINED; break; } //Get the key and value... std::string key; std::string val; key = aw_strToLower(line.substr(0,deli)); val = line.substr(deli+1); /* CHECK THE KEY IS VALID */ if(!isNameValid(key)){ m_error_line = lineNumber; m_error = AWESOME_ERROR_PARSING_INVALID_NAME; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } /* ENSURE THE NAME IS ALREADY TAKEN! */ if(findDuplicateKeyName((curGroup-1), key)) { m_error_line = lineNumber; m_error = AWESOME_ERROR_DUPLICATED_KEY; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } awesome_key_element newKey; newKey.m_key = aw_strToLower(key); newKey.m_value = val; newKey.key_type = figureType(val); m_list.at((curGroup-1)).m_elements.push_back(newKey); lineNumber++; } myfile.close(); } AWESOME_INI_KEY_TYPE awesome_ini::figureType(std::string val){ //Is number? size_t string_length = val.length(); val = aw_strToLower(val); /* IS IT A BOOL? */ if(string_length <= 5) { if(val.compare("true") == 0 || val.compare("false") == 0) { return AWESOME_TYPE_BOOL; } } //Is it a stirng? for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(isalpha(c) && (c < 48 || c > 57)) { return AWESOME_TYPE_STRING; } } bool isInt = true; for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(c == ''){ break; } if(c < 48|| c > 57) { isInt = false; break; } } if(isInt){ return AWESOME_TYPE_INT; } bool isFloat = true; for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(c == ''){ break; } if((c < 48|| c > 57) && c != 46) { isFloat = false; break; } } if(isFloat){ return AWESOME_TYPE_FLOAT; } return AWESOME_TYPE_VOID; } bool awesome_ini::throwError(AWESOME_ERROR_CODES error) { m_error = error; bool quit = false; if (AWI_REMOVE_DATA_ON_ERROR) { clearAll(); quit = true; } return quit; } //Does the key include characters not allowed? bool awesome_ini::isNameValid(std::string line) { size_t length = line.size(); for (size_t i = 0; i < length; i++) { unsigned char c = line[i]; if (!isalpha(c) && c != '_') { return false; } } return true; } awesome_ini::~awesome_ini() { clearAll(); } std::string awesome_ini::trim(std::string line) { size_t length = line.size(); if(length == 0) { return ""; } //Look for comments and strip them! std::size_t comindex = line.find(AWI_COMMENT_CHAR); if(comindex != std::string::npos){ line = line.substr(0, comindex); if(line.size() == 0){ return ""; } } bool ignoreSpaces = false; std::string destBuffer = ""; for (size_t i = 0; i < length; i++) { char c = line[i]; if(c == AWI_STRING_CHAR && !ignoreSpaces){ ignoreSpaces = true; continue; } if(c == AWI_STRING_CHAR && ignoreSpaces){ if(i > 1){ if(line[i-1] == '\'){ destBuffer += c; continue; } } ignoreSpaces = false; continue; } if ((c == ' ' || c == ' ' || c == ' ' || c == ' ') && !ignoreSpaces) { continue; } destBuffer += c; } return destBuffer; } std::string awesome_ini::aw_strToLower(std::string line) { size_t length = line.size(); if(length == 0) { return ""; } std::string dstBuffer; for (size_t i = 0; i < length; i++) { if(line[i]<='Z' && line[i]>='A') { char c = line[i]; dstBuffer += c-('Z'-'z'); continue; } dstBuffer += line[i]; } return dstBuffer; } AWESOME_ERROR_CODES awesome_ini::getError(void) { return m_error; } size_t awesome_ini::getErrorLine(void) { return m_error_line; } std::size_t awesome_ini::findGroup(std::string name) { size_t group_size = m_list.size(); if(group_size == 0){ return std::string::npos; } for(size_t i = 0; i<group_size; i++) { if(m_list.at(i).m_name.compare(name) == 0) { return i; } } return std::string::npos; } bool awesome_ini::findDuplicateGroupName(std::string name) { if(findGroup(name) != std::string::npos) { return true; } return false; } bool awesome_ini::findDuplicateKeyName(size_t group, std::string name) { size_t group_size = m_list.size(); if(group >= group_size){ return false; } size_t group_key_size = m_list.at(group).m_elements.size(); if(group_key_size == 0) { return false; } for(size_t i = 0; i<group_key_size; i++) { if(m_list.at(group).m_elements.at(i).m_key.compare(name) == 0){ return true; } } return false; } //delete all data! void awesome_ini::clearAll(void) { size_t group_size = m_list.size(); for(size_t i = 0; i<group_size; i++) { m_list.at(i).m_elements.clear(); } m_list.clear(); } //Gets key value. Returns data type void if nothing found and error. bool awesome_ini::getKeyType(AWESOME_INI_KEY_TYPE &type, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ type = m_list.at(group_index).m_elements.at(i).key_type; return true; } } return false; } //Gets key value. Returns data type void if nothing found and error. bool awesome_ini::getKeyType(AWESOME_INI_KEY_TYPE &type, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ type = m_list.at(group).m_elements.at(i).key_type; return true; } } return false; } bool awesome_ini::getKeyInt(int &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_INT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atoi(m_list.at(group_index).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyInt(int &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_INT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atoi(m_list.at(group).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyBool(bool &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } std::string buffer; for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_BOOL) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } buffer = m_list.at(group_index).m_elements.at(i).m_value; } } if(buffer.size() == 0){ m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } //Convert string to lowercase... buffer = aw_strToLower(buffer); p = false; if (buffer.compare("true") == 0) { p = true; } return true; } bool awesome_ini::getKeyBool(bool &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } std::string buffer; for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_BOOL) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } buffer = m_list.at(group).m_elements.at(i).m_value; } } if(buffer.size() == 0){ m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } //Convert string to lowercase... buffer = aw_strToLower(buffer); p = false; if (buffer.compare("true") == 0) { p = true; } return true; } bool awesome_ini::getKeyFloat(float &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_FLOAT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atof(m_list.at(group_index).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyFloat(float &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_FLOAT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atof(m_list.at(group).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyString(std::string &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_STRING) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = m_list.at(group_index).m_elements.at(i).m_value.c_str(); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyString(std::string &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_STRING) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = m_list.at(group).m_elements.at(i).m_value.c_str(); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } 4 . Cada iteración Tengo que obtener miles de coordenadas linealizadas, desinealizar una distancia de calcular entre las coordenadas 2D.

Actualmente, lo que hago es:

  #include "awesome_ini.h"  /* AUTHOR: Andrew McRobb  DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004  Copyright (C) 2015 Andrew McRobb <andrewmcrobb@gmail.com>  Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed.  DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION  0. You just DO WHAT THE FUCK YOU WANT TO.  */  awesome_ini::awesome_ini(std::string filename) {     m_error = AWESOME_ERROR_NONE;     m_error_line = 0;     std::ifstream myfile (filename);     if (!myfile.is_open())     {         m_error = AWESOME_ERROR_FILE_PATH;         return;     }      std::string line;     size_t lineNumber = 1;     size_t curGroup = 0;     while ( getline (myfile,line) )     {         line = trim(line);          if(line.size() < 1){             continue;         }          /* IS IT A NEW GROUP? */         if(line[0] == '['){              std::size_t endi = line.find_last_of(']');              if(endi == std::string::npos){                 m_error = AWESOME_ERROR_PARSING_INVALID_LINE;                 m_error_line = lineNumber;                  if(AWI_REMOVE_DATA_ON_ERROR){                     clearAll();                     return;                 }                  lineNumber++;                 continue;             }              std::string cat = aw_strToLower(line.substr(1, (endi-1)));              if(findDuplicateGroupName(cat)){                 m_error = AWESOME_ERROR_DUBLICATED_GROUP_NAME;                 m_error_line = lineNumber;                  if(AWI_REMOVE_DATA_ON_ERROR){                     clearAll();                     return;                 }                  lineNumber++;                 continue;             }              awesome_key_groups newGroup;             newGroup.m_name = cat;              m_list.push_back(newGroup);             curGroup++;             lineNumber++;             continue;         }          std::size_t deli = line.find(AWI_SEPERATOR_CHAR);          if(deli == std::string::npos){              m_error_line = lineNumber;             m_error = AWESOME_ERROR_PARSING_INVALID_SEPERATOR_POS;              if(AWI_REMOVE_DATA_ON_ERROR){                 clearAll();                 return;             }              lineNumber++;             continue;          }          if(curGroup == 0){             m_error_line = lineNumber;             m_error = AWESOME_ERROR_NO_GROUP_DEFINED;             break;         }           //Get the key and value...         std::string key;         std::string val;          key = aw_strToLower(line.substr(0,deli));         val = line.substr(deli+1);           /* CHECK THE KEY IS VALID */         if(!isNameValid(key)){             m_error_line = lineNumber;             m_error = AWESOME_ERROR_PARSING_INVALID_NAME;              if(AWI_REMOVE_DATA_ON_ERROR){                 clearAll();                 return;             }              lineNumber++;             continue;         }          /* ENSURE THE NAME IS ALREADY TAKEN! */         if(findDuplicateKeyName((curGroup-1), key))         {             m_error_line = lineNumber;             m_error = AWESOME_ERROR_DUPLICATED_KEY;              if(AWI_REMOVE_DATA_ON_ERROR){                 clearAll();                 return;             }              lineNumber++;             continue;         }           awesome_key_element  newKey;         newKey.m_key = aw_strToLower(key);         newKey.m_value = val;         newKey.key_type = figureType(val);          m_list.at((curGroup-1)).m_elements.push_back(newKey);          lineNumber++;     }      myfile.close(); }  AWESOME_INI_KEY_TYPE awesome_ini::figureType(std::string val){      //Is number?     size_t string_length = val.length();      val = aw_strToLower(val);      /* IS IT A BOOL? */     if(string_length <= 5)     {         if(val.compare("true") == 0 || val.compare("false") == 0)         {             return AWESOME_TYPE_BOOL;         }     }      //Is it a stirng?     for(size_t i = 0; i<string_length; i++)     {         char c = val.at(i);         if(isalpha(c) && (c < 48 || c > 57))         {             return AWESOME_TYPE_STRING;         }     }      bool isInt = true;     for(size_t i = 0; i<string_length; i++)     {         char c = val.at(i);          if(c == ''){             break;         }          if(c < 48|| c > 57)         {             isInt = false;             break;         }     }      if(isInt){         return AWESOME_TYPE_INT;     }      bool isFloat = true;     for(size_t i = 0; i<string_length; i++)     {          char c = val.at(i);          if(c == ''){             break;         }          if((c < 48|| c > 57) && c != 46)         {             isFloat = false;             break;         }     }      if(isFloat){         return AWESOME_TYPE_FLOAT;     }      return AWESOME_TYPE_VOID; }   bool awesome_ini::throwError(AWESOME_ERROR_CODES error) {     m_error = error;     bool quit = false;     if (AWI_REMOVE_DATA_ON_ERROR)     {         clearAll();         quit = true;     }      return quit; }   //Does the key include characters not allowed? bool awesome_ini::isNameValid(std::string line) {     size_t length = line.size();     for (size_t i = 0; i < length; i++)     {         unsigned char c = line[i];         if (!isalpha(c) && c != '_')         {             return false;         }     }      return true; }   awesome_ini::~awesome_ini() {     clearAll(); }  std::string awesome_ini::trim(std::string line) {     size_t length = line.size();      if(length == 0)     {         return "";     }      //Look for comments and strip them!      std::size_t comindex = line.find(AWI_COMMENT_CHAR);      if(comindex != std::string::npos){         line = line.substr(0, comindex);          if(line.size() == 0){             return "";         }     }      bool ignoreSpaces = false;     std::string destBuffer = "";      for (size_t i = 0; i < length; i++)     {         char c = line[i];          if(c == AWI_STRING_CHAR && !ignoreSpaces){             ignoreSpaces = true;             continue;         }          if(c == AWI_STRING_CHAR && ignoreSpaces){             if(i > 1){                 if(line[i-1] == '\'){                     destBuffer += c;                     continue;                 }             }             ignoreSpaces = false;             continue;         }          if ((c == ' ' || c == ' ' || c == ' ' || c == ' ') && !ignoreSpaces)         {             continue;         }            destBuffer += c;     }      return destBuffer; }  std::string awesome_ini::aw_strToLower(std::string line) {      size_t length = line.size();      if(length == 0)     {         return "";     }      std::string dstBuffer;      for (size_t i = 0; i < length; i++)     {         if(line[i]<='Z' && line[i]>='A')         {             char c = line[i];             dstBuffer += c-('Z'-'z');             continue;         }          dstBuffer += line[i];     }      return dstBuffer; }  AWESOME_ERROR_CODES awesome_ini::getError(void) {     return m_error; }  size_t awesome_ini::getErrorLine(void) {     return m_error_line; }  std::size_t   awesome_ini::findGroup(std::string name) {     size_t group_size = m_list.size();      if(group_size == 0){         return std::string::npos;     }      for(size_t i = 0; i<group_size; i++)     {         if(m_list.at(i).m_name.compare(name) == 0)         {             return i;         }     }      return std::string::npos; }  bool awesome_ini::findDuplicateGroupName(std::string name) {     if(findGroup(name) != std::string::npos)     {         return true;     }      return false; }  bool awesome_ini::findDuplicateKeyName(size_t group, std::string name) {     size_t group_size = m_list.size();      if(group >= group_size){         return false;     }      size_t group_key_size = m_list.at(group).m_elements.size();      if(group_key_size == 0) {         return false;     }      for(size_t i = 0; i<group_key_size; i++)     {         if(m_list.at(group).m_elements.at(i).m_key.compare(name) == 0){             return true;         }     }      return false; }   //delete all data! void awesome_ini::clearAll(void) {     size_t group_size = m_list.size();      for(size_t i = 0; i<group_size; i++)     {         m_list.at(i).m_elements.clear();     }      m_list.clear(); }  //Gets key value. Returns data type void if nothing found and error. bool awesome_ini::getKeyType(AWESOME_INI_KEY_TYPE &type, std::string group, std::string key) {     std::size_t group_index = findGroup(group);      if(group_index == std::string::npos){         m_error = AWESOME_ERROR_GROUP_NOT_FOUND;         return false;     }      size_t key_size = m_list.at(group_index).m_elements.size();      if(key_size == 0){         return false;     }      for(size_t i = 0; i<key_size; i++){         if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){             type = m_list.at(group_index).m_elements.at(i).key_type;             return true;         }     }      return false; }  //Gets key value. Returns data type void if nothing found and error. bool awesome_ini::getKeyType(AWESOME_INI_KEY_TYPE &type, size_t group, std::string key) {     std::size_t group_size = m_list.size();     if(group >= group_size){         m_error = AWESOME_ERROR_GROUP_NOT_FOUND;         return false;     }      size_t key_size = m_list.at(group).m_elements.size();      if(key_size == 0){         return false;     }      for(size_t i = 0; i<key_size; i++){         if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){             type = m_list.at(group).m_elements.at(i).key_type;             return true;         }     }      return false; }     bool awesome_ini::getKeyInt(int &p, std::string group, std::string key) {     std::size_t group_index = findGroup(group);      if(group_index == std::string::npos){         m_error = AWESOME_ERROR_GROUP_NOT_FOUND;         return false;     }       size_t key_size = m_list.at(group_index).m_elements.size();      if(key_size == 0){         return false;     }      for(size_t i = 0; i<key_size; i++){         if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){              if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_INT) {                 m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED;                 return false;             }              p = atoi(m_list.at(group_index).m_elements.at(i).m_value.c_str());             return true;         }     }      m_error = AWESOME_ERROR_KEY_NOT_FOUND;     return false; }  bool awesome_ini::getKeyInt(int &p, size_t group, std::string key) {     std::size_t group_size = m_list.size();     if(group >= group_size){         m_error = AWESOME_ERROR_GROUP_NOT_FOUND;         return false;     }      size_t key_size = m_list.at(group).m_elements.size();      if(key_size == 0){         return false;     }      for(size_t i = 0; i<key_size; i++){         if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){              if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_INT) {                 m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED;                 return false;             }              p = atoi(m_list.at(group).m_elements.at(i).m_value.c_str());             return true;         }     }      m_error = AWESOME_ERROR_KEY_NOT_FOUND;     return false; }   bool awesome_ini::getKeyBool(bool &p, std::string group, std::string key) {     std::size_t group_index = findGroup(group);      if(group_index == std::string::npos){         m_error = AWESOME_ERROR_GROUP_NOT_FOUND;         return false;     }      size_t key_size = m_list.at(group_index).m_elements.size();      if(key_size == 0){         return false;     }      std::string buffer;      for(size_t i = 0; i<key_size; i++){         if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){              if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_BOOL) {                 m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED;                 return false;             }             buffer = m_list.at(group_index).m_elements.at(i).m_value;         }     }      if(buffer.size() == 0){         m_error = AWESOME_ERROR_KEY_NOT_FOUND;         return false;     }      //Convert string to lowercase...     buffer = aw_strToLower(buffer);      p = false;     if (buffer.compare("true") == 0)     {         p = true;     }      return true; }  bool awesome_ini::getKeyBool(bool &p, size_t group, std::string key) {      std::size_t group_size = m_list.size();     if(group >= group_size){         m_error = AWESOME_ERROR_GROUP_NOT_FOUND;         return false;     }      size_t key_size = m_list.at(group).m_elements.size();      if(key_size == 0){         return false;     }      std::string buffer;      for(size_t i = 0; i<key_size; i++){         if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){             if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_BOOL) {                 m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED;                 return false;             }             buffer = m_list.at(group).m_elements.at(i).m_value;         }     }      if(buffer.size() == 0){         m_error = AWESOME_ERROR_KEY_NOT_FOUND;         return false;     }      //Convert string to lowercase...     buffer = aw_strToLower(buffer);      p = false;     if (buffer.compare("true") == 0)     {         p = true;     }      return true; }    bool awesome_ini::getKeyFloat(float &p, std::string group, std::string key) {     std::size_t group_index = findGroup(group);      if(group_index == std::string::npos){         m_error = AWESOME_ERROR_GROUP_NOT_FOUND;         return false;     }      size_t key_size = m_list.at(group_index).m_elements.size();      if(key_size == 0){         return false;     }      for(size_t i = 0; i<key_size; i++){         if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){             if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_FLOAT) {                 m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED;                 return false;             }             p = atof(m_list.at(group_index).m_elements.at(i).m_value.c_str());             return true;         }     }      m_error = AWESOME_ERROR_KEY_NOT_FOUND;     return false; }  bool awesome_ini::getKeyFloat(float &p, size_t group, std::string key) {     std::size_t group_size = m_list.size();     if(group >= group_size){         m_error = AWESOME_ERROR_GROUP_NOT_FOUND;         return false;     }      size_t key_size = m_list.at(group).m_elements.size();      if(key_size == 0){         return false;     }      for(size_t i = 0; i<key_size; i++){         if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){             if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_FLOAT) {                 m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED;                 return false;             }             p = atof(m_list.at(group).m_elements.at(i).m_value.c_str());             return true;         }     }      m_error = AWESOME_ERROR_KEY_NOT_FOUND;     return false; }  bool awesome_ini::getKeyString(std::string &p, std::string group, std::string key) {     std::size_t group_index = findGroup(group);      if(group_index == std::string::npos){         m_error = AWESOME_ERROR_GROUP_NOT_FOUND;         return false;     }      size_t key_size = m_list.at(group_index).m_elements.size();      if(key_size == 0){         return false;     }      for(size_t i = 0; i<key_size; i++){         if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){             if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_STRING) {                 m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED;                 return false;             }             p = m_list.at(group_index).m_elements.at(i).m_value.c_str();             return true;         }     }      m_error = AWESOME_ERROR_KEY_NOT_FOUND;     return false; }  bool awesome_ini::getKeyString(std::string &p, size_t group, std::string key) {     std::size_t group_size = m_list.size();     if(group >= group_size){         m_error = AWESOME_ERROR_GROUP_NOT_FOUND;         return false;     }      size_t key_size = m_list.at(group).m_elements.size();      if(key_size == 0){         return false;     }      for(size_t i = 0; i<key_size; i++){         if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){             if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_STRING) {                 m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED;                 return false;             }             p = m_list.at(group).m_elements.at(i).m_value.c_str();             return true;         }     }      m_error = AWESOME_ERROR_KEY_NOT_FOUND;      return false; } 5  

¿Cómo podría mejorar eso? ¿Cuál es la forma más temerosa de tomar dos de esos valores de enteros, recuperar  #include "awesome_ini.h" /* AUTHOR: Andrew McRobb DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 Copyright (C) 2015 Andrew McRobb <andrewmcrobb@gmail.com> Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. You just DO WHAT THE FUCK YOU WANT TO. */ awesome_ini::awesome_ini(std::string filename) { m_error = AWESOME_ERROR_NONE; m_error_line = 0; std::ifstream myfile (filename); if (!myfile.is_open()) { m_error = AWESOME_ERROR_FILE_PATH; return; } std::string line; size_t lineNumber = 1; size_t curGroup = 0; while ( getline (myfile,line) ) { line = trim(line); if(line.size() < 1){ continue; } /* IS IT A NEW GROUP? */ if(line[0] == '['){ std::size_t endi = line.find_last_of(']'); if(endi == std::string::npos){ m_error = AWESOME_ERROR_PARSING_INVALID_LINE; m_error_line = lineNumber; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } std::string cat = aw_strToLower(line.substr(1, (endi-1))); if(findDuplicateGroupName(cat)){ m_error = AWESOME_ERROR_DUBLICATED_GROUP_NAME; m_error_line = lineNumber; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } awesome_key_groups newGroup; newGroup.m_name = cat; m_list.push_back(newGroup); curGroup++; lineNumber++; continue; } std::size_t deli = line.find(AWI_SEPERATOR_CHAR); if(deli == std::string::npos){ m_error_line = lineNumber; m_error = AWESOME_ERROR_PARSING_INVALID_SEPERATOR_POS; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } if(curGroup == 0){ m_error_line = lineNumber; m_error = AWESOME_ERROR_NO_GROUP_DEFINED; break; } //Get the key and value... std::string key; std::string val; key = aw_strToLower(line.substr(0,deli)); val = line.substr(deli+1); /* CHECK THE KEY IS VALID */ if(!isNameValid(key)){ m_error_line = lineNumber; m_error = AWESOME_ERROR_PARSING_INVALID_NAME; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } /* ENSURE THE NAME IS ALREADY TAKEN! */ if(findDuplicateKeyName((curGroup-1), key)) { m_error_line = lineNumber; m_error = AWESOME_ERROR_DUPLICATED_KEY; if(AWI_REMOVE_DATA_ON_ERROR){ clearAll(); return; } lineNumber++; continue; } awesome_key_element newKey; newKey.m_key = aw_strToLower(key); newKey.m_value = val; newKey.key_type = figureType(val); m_list.at((curGroup-1)).m_elements.push_back(newKey); lineNumber++; } myfile.close(); } AWESOME_INI_KEY_TYPE awesome_ini::figureType(std::string val){ //Is number? size_t string_length = val.length(); val = aw_strToLower(val); /* IS IT A BOOL? */ if(string_length <= 5) { if(val.compare("true") == 0 || val.compare("false") == 0) { return AWESOME_TYPE_BOOL; } } //Is it a stirng? for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(isalpha(c) && (c < 48 || c > 57)) { return AWESOME_TYPE_STRING; } } bool isInt = true; for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(c == ''){ break; } if(c < 48|| c > 57) { isInt = false; break; } } if(isInt){ return AWESOME_TYPE_INT; } bool isFloat = true; for(size_t i = 0; i<string_length; i++) { char c = val.at(i); if(c == ''){ break; } if((c < 48|| c > 57) && c != 46) { isFloat = false; break; } } if(isFloat){ return AWESOME_TYPE_FLOAT; } return AWESOME_TYPE_VOID; } bool awesome_ini::throwError(AWESOME_ERROR_CODES error) { m_error = error; bool quit = false; if (AWI_REMOVE_DATA_ON_ERROR) { clearAll(); quit = true; } return quit; } //Does the key include characters not allowed? bool awesome_ini::isNameValid(std::string line) { size_t length = line.size(); for (size_t i = 0; i < length; i++) { unsigned char c = line[i]; if (!isalpha(c) && c != '_') { return false; } } return true; } awesome_ini::~awesome_ini() { clearAll(); } std::string awesome_ini::trim(std::string line) { size_t length = line.size(); if(length == 0) { return ""; } //Look for comments and strip them! std::size_t comindex = line.find(AWI_COMMENT_CHAR); if(comindex != std::string::npos){ line = line.substr(0, comindex); if(line.size() == 0){ return ""; } } bool ignoreSpaces = false; std::string destBuffer = ""; for (size_t i = 0; i < length; i++) { char c = line[i]; if(c == AWI_STRING_CHAR && !ignoreSpaces){ ignoreSpaces = true; continue; } if(c == AWI_STRING_CHAR && ignoreSpaces){ if(i > 1){ if(line[i-1] == '\'){ destBuffer += c; continue; } } ignoreSpaces = false; continue; } if ((c == ' ' || c == ' ' || c == ' ' || c == ' ') && !ignoreSpaces) { continue; } destBuffer += c; } return destBuffer; } std::string awesome_ini::aw_strToLower(std::string line) { size_t length = line.size(); if(length == 0) { return ""; } std::string dstBuffer; for (size_t i = 0; i < length; i++) { if(line[i]<='Z' && line[i]>='A') { char c = line[i]; dstBuffer += c-('Z'-'z'); continue; } dstBuffer += line[i]; } return dstBuffer; } AWESOME_ERROR_CODES awesome_ini::getError(void) { return m_error; } size_t awesome_ini::getErrorLine(void) { return m_error_line; } std::size_t awesome_ini::findGroup(std::string name) { size_t group_size = m_list.size(); if(group_size == 0){ return std::string::npos; } for(size_t i = 0; i<group_size; i++) { if(m_list.at(i).m_name.compare(name) == 0) { return i; } } return std::string::npos; } bool awesome_ini::findDuplicateGroupName(std::string name) { if(findGroup(name) != std::string::npos) { return true; } return false; } bool awesome_ini::findDuplicateKeyName(size_t group, std::string name) { size_t group_size = m_list.size(); if(group >= group_size){ return false; } size_t group_key_size = m_list.at(group).m_elements.size(); if(group_key_size == 0) { return false; } for(size_t i = 0; i<group_key_size; i++) { if(m_list.at(group).m_elements.at(i).m_key.compare(name) == 0){ return true; } } return false; } //delete all data! void awesome_ini::clearAll(void) { size_t group_size = m_list.size(); for(size_t i = 0; i<group_size; i++) { m_list.at(i).m_elements.clear(); } m_list.clear(); } //Gets key value. Returns data type void if nothing found and error. bool awesome_ini::getKeyType(AWESOME_INI_KEY_TYPE &type, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ type = m_list.at(group_index).m_elements.at(i).key_type; return true; } } return false; } //Gets key value. Returns data type void if nothing found and error. bool awesome_ini::getKeyType(AWESOME_INI_KEY_TYPE &type, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ type = m_list.at(group).m_elements.at(i).key_type; return true; } } return false; } bool awesome_ini::getKeyInt(int &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_INT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atoi(m_list.at(group_index).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyInt(int &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_INT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atoi(m_list.at(group).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyBool(bool &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } std::string buffer; for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_BOOL) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } buffer = m_list.at(group_index).m_elements.at(i).m_value; } } if(buffer.size() == 0){ m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } //Convert string to lowercase... buffer = aw_strToLower(buffer); p = false; if (buffer.compare("true") == 0) { p = true; } return true; } bool awesome_ini::getKeyBool(bool &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } std::string buffer; for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_BOOL) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } buffer = m_list.at(group).m_elements.at(i).m_value; } } if(buffer.size() == 0){ m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } //Convert string to lowercase... buffer = aw_strToLower(buffer); p = false; if (buffer.compare("true") == 0) { p = true; } return true; } bool awesome_ini::getKeyFloat(float &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_FLOAT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atof(m_list.at(group_index).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyFloat(float &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_FLOAT) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = atof(m_list.at(group).m_elements.at(i).m_value.c_str()); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyString(std::string &p, std::string group, std::string key) { std::size_t group_index = findGroup(group); if(group_index == std::string::npos){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group_index).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group_index).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group_index).m_elements.at(i).key_type != AWESOME_TYPE_STRING) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = m_list.at(group_index).m_elements.at(i).m_value.c_str(); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } bool awesome_ini::getKeyString(std::string &p, size_t group, std::string key) { std::size_t group_size = m_list.size(); if(group >= group_size){ m_error = AWESOME_ERROR_GROUP_NOT_FOUND; return false; } size_t key_size = m_list.at(group).m_elements.size(); if(key_size == 0){ return false; } for(size_t i = 0; i<key_size; i++){ if(m_list.at(group).m_elements.at(i).m_key.compare(key) == 0){ if(m_list.at(group).m_elements.at(i).key_type != AWESOME_TYPE_STRING) { m_error = AWESOME_ERROR_INVALID_DATA_TYPE_RETRIVED; return false; } p = m_list.at(group).m_elements.at(i).m_value.c_str(); return true; } } m_error = AWESOME_ERROR_KEY_NOT_FOUND; return false; } 6  99887766555443317 y luego calcule la Distancia 2D entre dichos puntos? Estoy abierto a todas las sugerencias, incluidas las instrucciones de SIMD.

Original en ingles

In a simulation of mine, for which performance is paramount, I have the following bottleneck.

I have a huge 2D grid of dimensions width and height, whose dimensions are stored in linearized form, i.e. positions at x and y are stored as one integer x + y*width. Every iteration I have to get thousands of such linearized coordinates, de-linearize an calculate distance between 2d coordinates.

Currently, what I do is:

y1 = linPos1 / width; //int divided by int disregards remainders x1 = linPos1 - width * y1;  y2 = linPos2 / width; //int divided by int disregards remainders x2 = linPos2 - width * y2;  int xDiff = x2-x1; int yDiff = y2-y1; double distance = sqrt(xDiff*xDiff  + yDiff*yDiff); 

How could I improve upon that? What is the most performant way to take two of such integer values, retrieve back x and y and then calculate the 2D distance between said points? I am open to all suggestions, including SIMD instructions.

Lista de respuestas

3

La mejor respuesta

Lo que está haciendo es empacar las dos coordenadas enteras en un solo entero, luego desempaciéndolas.

Supongamos que $texto {altura} leq texto {anchth}$, deja  w = width . Traduzca la celosía para que $0 leq x, y leq w-1$.

Uso de estas suposiciones, el embalaje se puede hacer escribiendo las coordenadas en la base  w . Por ejemplo, si w = 102 , x=43 , y y=74 , entonces la representación es w*y + x = 7*10 + 4 = 74 .

Usando nuestras suposiciones Esta es una función inyectiva, es decir, a un par $(x, y)$, existe a lo sumo un $k$ de tal manera que $k = wy + x$, y cada una tal $K$ determinar de manera única la $(x, y)$. Esto significa que el desembalaje del embalaje está bien definido, lo cual es excelente: los mismos puntos tendrán las mismas representaciones, y una representación corresponde a exactamente un punto.

Su código,

  y = k / w; x = k - w * y;   

podría ser escrito algunas maneras diferentes, por ejemplo. usando  % ,

  y = k / w x = k % w  

o usando  std::div  .

Los compiladores modernos compilarán todos estos en la misma instrucción:  w0 , por lo que no tiene que preocuparse por esta parte, simplemente no olvides decirle a su compilador que se optimice ligeramente. Por ejemplo,  w1 necesita el w2 bandera.

Así que eso es tan bueno como se hace, a menos que podamos usar una forma más rápida de división entera (de ahora en adelante, simplemente división).

Si un número está en la base $b$, entonces es realmente fácil dividirlo por poderes de $b$: simplemente cambia los números alrededor; p.ej.  w3 , 99887766555443314 .

Eso está bien y bien, pero las operaciones de cadena no van a ser más rápidas que  w5 . Afortunadamente, no necesitamos aquellos, porque al elegir $W = 2 ^ n$, podemos apalancar los turnos de bits y, y hacer exactamente lo mismo para nosotros, realmente rápido.

Encontremos el más pequeño $n in mathbb n$, tal que $w leq 2 ^ n$. Sea $w = 2 ^ n$. Tal vez no uses algunas coordenadas, pero eso no es realmente un problema. Ahora nuestro código de división se verá así.

  w6 

aquí  w7  será el primer  w8 th bits of , y w = 10020 será el resto. Por ejemplo, si w = 101 , w = 102 , luego 99887776655443323 , w = 104 . < / p>

Ahora veamos si los compiladores son lo suficientemente inteligentes como para hacerlo automáticamente.

  w = 105  

Veamos el código de ensamblaje generado desde el código anterior, si permitimos que el compilador optimice un poco.

  w = 106 

Como puede ver, además de algunas comprobaciones de registro, los dos códigos son idénticos. De hecho, después de especificar que estamos trabajando con enteros sin firmar, obtenemos la misma salida:

  w = 107 

Esto significa que podemos mantener a nuestros operadores más legibles:  w = 108 , y  w = 109 . Hurray!

Ahora veamos la última parte de su código, y vamos a cambiarlo a una fórmula más general.

  x=40 

Dónde  x=411 es una función que calcula una distancia . En su caso, 99887766555443332 corresponde a la métrica euclidiana,

  x=43  

Dependiendo de sus necesidades, podría usar otras métricas; A medida que trabaja en una celosía entera, le sugiero que eche un vistazo a la metro de taxixab . Su cálculo es más rápido, y hay menos espacio para errores numéricos.

  x=44 

Implementar estos cambios resultan en el código, lo cual es un tiempo constante más rápido que su el original.

Si bien fue divertido descubrir, dudo que este sea el tipo de aceleración que esperabas. Creo que optimizar otras partes de su código podría tener mayores beneficios. Tal vez considere publicarlos como una pregunta separada.

What you are doing is packing the two integer coordinates into a single integer, then unpacking them.

Let us assume that \$\text{height} \leq \text{width}\$, let w = width. Translate the lattice so that \$0 \leq x,y\leq w-1\$.

Using these assumptions, the packing can be done by writing the coordinates in base w. For example, if w = 10, x=4, and y=7, then the representation is w*y + x = 7*10 + 4 = 74.

Using our assumptions this is an injective function, i.e. to one pair \$(x,y)\$ there exists at most one \$k\$ such that \$k=wy+x\$, and each such \$k\$ uniquely determine the \$(x,y)\$. This means that the packing-unpacking is well-defined, which is great: same points will have the same representations, and a representation corresponds to exactly one point.

y = k / w; x = k - w * y; 

could be written a few different ways, e.g. using %,

y = k / w x = k % w 

or by using std::div.

Modern compilers will compile all of these to the same instruction: idivl, so you don't have to worry about this part, just don't forget to tell your compiler to optimize slightly. For example, g++ needs the -O1 flag.

So that's about as good as it gets, unless we can use some faster form of integer division(from now on, simply division).

If a number is in base \$b\$, then it's really easy to divide it by powers of \$b\$: just shift the numbers around; e.g. 1234/10^3 = 1, 1234 % 10^3 = 4.

That's all fine and well, but string operations aren't going to be faster than idivl. Luckily we don't need those, because by choosing \$w=2^n\$, we can leverage bit-shifts, and bitwise-and to do exactly the same for us, really fast.

Let's find the smallest \$n \in \mathbb N\$, such that \$w \leq 2^n\$. Let \$w = 2^n\$. Perhaps you won't use a few coordinates, but that's not really a problem. Now our division code will look like this.

y = k >> n x = k & ((1 << n) - 1) 

Here x will be the first nth bits of k, and y will be the rest. For example, if k = 1101, n=2, then
x = 1101 & ((1 << 2) - 1) = 1101 & (0100 - 0001) = 1101 & 0011 = 0001 = 01,
y = 1101 >> 2 = 0011 = 11.

Now let's see if the compilers are clever enough to do this for us automatically.

int func1(int a) {     int x = a / 1024;     int y = a % 1024;     return x+y; }  int func2(int a) {     int x = a >> 10;     int y = a & ((1 << 10) - 1);     return x+y; } 

Let's see the assembly code generated from the code above, if we allow the compiler to optimize a bit.

_Z5func1i:     leal    1023(%rdi), %eax     testl   %edi, %edi     movl    %edi, %edx     cmovns  %edi, %eax     sarl    $31, %edx shrl$22, %edx     sarl    $10, %eax addl %edx, %edi andl$1023, %edi     subl    %edx, %edi     addl    %edi, %eax     ret  _Z5func2j:     movl    %edi, %eax     andl    $1023, %edi shrl$10, %eax     addl    %edi, %eax     ret 

As you can see, besides some sign-checking, the two codes are identical. In fact, after specifying that we are working with unsigned integers, we get the same output:

    movl    %edi, %eax     andl    $1023, %edi shrl$10, %eax     addl    %edi, %eax     ret 

This means that we can keep our more readable operators: %, and /. Hurray!

Now let's look at the last part of your code, and let's change it to a more general formula.

double distance = metric(xDiff,yDiff); 

Where metric is a function calculating a distance. In your case, metric corresponds to the Euclidean metric,

double metric(int dx, int dy) {    return std::sqrt(dx*dx+dy*dy); } 

Depending on your needs, you could use other metrics; as you are working on an integer lattice, I'd suggest you take a look at the taxicab metric. Its calculation is faster, and there is less room for numerical errors.

double metric(int dx, int dy) {    return std::abs(dx) + std::abs(dy); } 

Implementing these changes result in code, which is a constant time faster, than your original one.

While it was fun figuring out, I doubt this is the kind of speed up you were hoping for. I think optimizing other parts of your code could have greater benefits. Perhaps consider posting them as a separate question.

0

Puede obtener tanto el cociente y y el resto x usando solo una llamada a  std::div(linPos, width)  .

Si  width es una potencia de 2, entonces puede obtener rápidamente el cociente utilizando un turno de derecha ( 9988777665544332 ), y el resto usando bitwise y (< Código> & ).

You can obtain both the quotient y and the remainder x using just one call to std::div(linPos, width).

If width happens to be a power of 2, then you can quickly get the quotient using a right shift (>>), and the remainder using bitwise AND (&).

3  Clases NODE2D y NODE3D implementadas utilizando un decorador compartido  ( Node2d and node3d classes implemented using a shared decorator )
Editar: He hecho otro Ir a esto usando Metaclasses aquí . Creo que es un enfoque mucho mejor. Tengo las siguientes clases. validator es un decorador que ...

17  Implementación vectorial (física)  ( Vector physics implementation )
Recientemente comencé a aprender Java, y decidí implementar un sistema de vectores básico para otro sistema de partículas que estaba construyendo. join()9 ...

14  Comparación con el infinito al verificar si un punto está por encima de una línea  ( Comparison to infinity when checking if a point is above a line )
Tengo una función que se llama en un bucle apretado. He perfilado mi código y aquí es donde está mi cuello de botella más grande. La función es bastante simpl...

Recientemente creé una implementación de Quadtree en C ++. Varía ligeramente de la mayoría de las implementaciones. En lugar de almacenar elementos, solo or...

5  Clase de vectores matemáticas fuertemente planteladas  ( Heavily templated mathematical vector class )
Comencé a escribir una biblioteca para el álgebra lineal para uso personal, pero también para la revitilización de mi C ++. A continuación se muestra la pri...

10  Encuentra el hogar visible no visible más cercano  ( Find the closest unvisited visible home )
Estoy escribiendo un juego más alto de 2D donde realizo una gran cantidad de búsquedas "más cercanas" entre un punto y todo el resto de los puntos. En este ...

5  Fórmula Haversine en Clojure  ( Haversine formula in clojure )
Implementé el fórmula haversine para calcular la distancia entre dos (latitud , longitud) coordenadas. Me preguntaba si se ve natural para los programador...

21  Conversión de coordenadas polares a coordenadas rectangulares  ( Converting from polar coordinates to rectangular coordinates )
Este es un rendimiento crítico. Medí y determiné que el uso de 99887766655443319 es más rápido que usar el método 99887766655443320 . Soy consciente de q...