diff --git a/opm/parser/eclipse/CMakeLists.txt b/opm/parser/eclipse/CMakeLists.txt index f1c46425e..ece245f8c 100644 --- a/opm/parser/eclipse/CMakeLists.txt +++ b/opm/parser/eclipse/CMakeLists.txt @@ -126,6 +126,7 @@ EclipseState/Schedule/CompletionSet.hpp EclipseState/Schedule/ScheduleEnums.hpp EclipseState/Schedule/GroupTreeNode.hpp EclipseState/Schedule/GroupTree.hpp +EclipseState/Schedule/OrderedMap.hpp # EclipseState/Grid/EclipseGrid.hpp # diff --git a/opm/parser/eclipse/EclipseState/Schedule/OrderedMap.hpp b/opm/parser/eclipse/EclipseState/Schedule/OrderedMap.hpp new file mode 100644 index 000000000..fd519091b --- /dev/null +++ b/opm/parser/eclipse/EclipseState/Schedule/OrderedMap.hpp @@ -0,0 +1,90 @@ +/* + Copyright 2014 Statoil ASA. + + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . + */ + +#include +#include +#include +#include + + +namespace Opm { + +template +class OrderedMap { +private: + std::unordered_map m_map; + std::vector m_vector; + +public: + bool hasKey(const std::string& key) const { + auto iter = m_map.find(key); + if (iter == m_map.end()) + return false; + else + return true; + } + + + void insert(std::string key, T value) { + if (hasKey(key)) { + auto iter = m_map.find( key ); + size_t index = iter->second; + m_vector[index] = value; + } else { + size_t index = m_vector.size(); + m_vector.push_back( value ); + m_map.insert( std::pair(key , index)); + } + } + + + T get(const std::string& key) const { + auto iter = m_map.find( key ); + if (iter == m_map.end()) + throw std::invalid_argument("Key not found"); + else { + size_t index = iter->second; + return get(index); + } + } + + + T get(size_t index) const { + if (index >= m_vector.size()) + throw std::invalid_argument("Invalid index"); + return m_vector[index]; + } + + + size_t size() const { + return m_vector.size(); + } + + + typename std::vector::const_iterator begin() const { + return m_vector.begin(); + } + + + typename std::vector::const_iterator end() const { + return m_vector.end(); + } +}; +} + diff --git a/opm/parser/eclipse/EclipseState/Schedule/tests/CMakeLists.txt b/opm/parser/eclipse/EclipseState/Schedule/tests/CMakeLists.txt index 699ecdf07..247990e09 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/tests/CMakeLists.txt +++ b/opm/parser/eclipse/EclipseState/Schedule/tests/CMakeLists.txt @@ -23,6 +23,11 @@ target_link_libraries(runGroupTests Parser ${Boost_LIBRARIES}) add_test(NAME runGroupTests WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${TEST_MEMCHECK_TOOL} ${EXECUTABLE_OUTPUT_PATH}/runGroupTests ) +add_executable(runOrderedMapTests OrderedMapTests.cpp) +target_link_libraries(runOrderedMapTests Parser ${Boost_LIBRARIES}) +add_test(NAME runOrderedMapTests WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${TEST_MEMCHECK_TOOL} ${EXECUTABLE_OUTPUT_PATH}/runOrderedMapTests ) + + add_executable(runScheduleEnumTests ScheduleEnumTests.cpp) target_link_libraries(runScheduleEnumTests Parser ${Boost_LIBRARIES}) add_test(NAME runScheduleEnumTests WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${TEST_MEMCHECK_TOOL} ${EXECUTABLE_OUTPUT_PATH}/runScheduleEnumTests ) diff --git a/opm/parser/eclipse/EclipseState/Schedule/tests/OrderedMapTests.cpp b/opm/parser/eclipse/EclipseState/Schedule/tests/OrderedMapTests.cpp new file mode 100644 index 000000000..1edd50684 --- /dev/null +++ b/opm/parser/eclipse/EclipseState/Schedule/tests/OrderedMapTests.cpp @@ -0,0 +1,73 @@ +/* + Copyright 2014 Statoil ASA. + + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . + */ + +#include +#include +#include + +#define BOOST_TEST_MODULE ScheduleTests +#include +#include + +#include + + +BOOST_AUTO_TEST_CASE( check_empty) { + Opm::OrderedMap map; + BOOST_CHECK_EQUAL( 0U , map.size() ); + BOOST_CHECK( !map.hasKey("KEY")); + BOOST_CHECK_THROW( map.get( 0 ) , std::invalid_argument); + BOOST_CHECK_THROW( map.get( "KEY" ) , std::invalid_argument); +} + + +BOOST_AUTO_TEST_CASE( check_order ) { + Opm::OrderedMap map; + map.insert("CKEY1" , "Value1"); + map.insert("BKEY2" , "Value2"); + map.insert("AKEY3" , "Value3"); + + BOOST_CHECK_EQUAL( 3U , map.size() ); + BOOST_CHECK( map.hasKey("CKEY1")); + BOOST_CHECK( map.hasKey("BKEY2")); + BOOST_CHECK( map.hasKey("AKEY3")); + + BOOST_CHECK_EQUAL( "Value1" , map.get("CKEY1")); + BOOST_CHECK_EQUAL( "Value1" , map.get( 0 )); + + BOOST_CHECK_EQUAL( "Value2" , map.get("BKEY2")); + BOOST_CHECK_EQUAL( "Value2" , map.get( 1 )); + + BOOST_CHECK_EQUAL( "Value3" , map.get("AKEY3")); + BOOST_CHECK_EQUAL( "Value3" , map.get( 2 )); + + map.insert( "CKEY1" , "NewValue1"); + BOOST_CHECK_EQUAL( "NewValue1" , map.get("CKEY1")); + BOOST_CHECK_EQUAL( "NewValue1" , map.get( 0 )); + + { + std::vector values; + for (auto iter = map.begin(); iter != map.end(); ++iter) + values.push_back( *iter ); + + BOOST_CHECK_EQUAL( values[0] , "NewValue1"); + BOOST_CHECK_EQUAL( values[1] , "Value2"); + BOOST_CHECK_EQUAL( values[2] , "Value3"); + } +}