diff --git a/libs/util/include/psemek/util/at.hpp b/libs/util/include/psemek/util/at.hpp new file mode 100644 index 00000000..fdf7dec5 --- /dev/null +++ b/libs/util/include/psemek/util/at.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include +#include + +#include + +namespace psemek::util +{ + + struct key_error_base + : exception + { + using exception::exception; + }; + + template + struct key_error + : key_error_base + { + key_error(Key const & key, boost::stacktrace::stacktrace stacktrace = {}) + : key_error_base(util::to_string("no such key: ", key), std::move(stacktrace)) + , key_(key) + {} + + Key const & key() const + { + return key_; + } + + private: + Key key_; + }; + + template + auto & at(Container && container, Key const & key) + { + if (auto it = container.find(key); it != container.end()) + return it->second; + + throw key_error(key); + } + + template + auto & at(std::vector && container, Key const & key) + { + if (key < container.size()) + return container[key]; + + throw key_error(key); + } + +}