Last active
December 18, 2016 13:01
-
-
Save tell/4bbcca7e69a9db1f37a6880099e821bd to your computer and use it in GitHub Desktop.
Java Properties like map on C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### https://raw.github.com/github/gitignore/afbff9027d02ccfc680e031f6c295f79ad61662d/C++.gitignore | |
# Prerequisites | |
*.d | |
# Compiled Object files | |
*.slo | |
*.lo | |
*.o | |
*.obj | |
# Precompiled Headers | |
*.gch | |
*.pch | |
# Compiled Dynamic libraries | |
*.so | |
*.dylib | |
*.dll | |
# Fortran module files | |
*.mod | |
*.smod | |
# Compiled Static libraries | |
*.lai | |
*.la | |
*.a | |
*.lib | |
# Executables | |
*.exe | |
*.out | |
*.app | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// vim: set expandtab : | |
#include <iostream> | |
#include <boost/optional.hpp> | |
#include <boost/lexical_cast.hpp> | |
#include "properties.hpp" | |
using namespace std; | |
int main(int argc, char *argv[]) { | |
if (argc < 2) { return 1; } | |
string x(argv[1]); | |
string key = "argv1"; | |
cout << key << " is " << x << endl; | |
tell::Properties mc{{key, x}}; | |
if (auto a = mc.get(key)) { | |
cout << "get() is " << *a << endl; | |
} | |
if (auto a = mc.getInt(key)) { | |
cout << "getInt() is " << *a << endl; | |
} | |
if (auto a = mc.getInt64(key)) { | |
cout << "getInt64() is " << *a << endl; | |
} | |
if (auto a = mc.getFloat(key)) { | |
cout << "getFloat() is " << *a << endl; | |
} | |
if (auto a = mc.getDouble(key)) { | |
cout << "getDouble() is " << *a << endl; | |
} | |
return 0; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CC = $(CXX) | |
CPPFLAGS += -std=c++11 | |
CXXFLAGS += -Ofast | |
%.out: %.o | |
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@ | |
all: lc.out | |
lc.o: properties.hpp |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// vim: set expandtab : | |
#pragma once | |
#include <unordered_map> | |
#include <boost/optional.hpp> | |
#include <boost/lexical_cast.hpp> | |
namespace tell { | |
template<class T> | |
using opt = boost::optional<T>; | |
constexpr auto none = boost::none; | |
using boost::lexical_cast; | |
using boost::conversion::try_lexical_convert; | |
namespace details { | |
template<class T> | |
opt<T> getGeneric(const std::string& repr) { | |
T result; | |
if (try_lexical_convert<T>(repr, result)) { | |
return result; | |
} else { | |
return none; | |
} | |
} | |
#if defined(DETAILS_GET_MEMBERS_BY_GET_GENERIC) | |
#error "DETAILS_GET_MEMBERS_BY_GET_GENERIC is already defined." | |
#endif | |
#define DETAILS_GET_MEMBERS_BY_GET_GENERIC(type, name) \ | |
opt< type > name (const std::string& key) const { \ | |
return details::getGeneric< type >(map_.at(key)); \ | |
} | |
} // namespace details | |
class Properties { | |
std::unordered_map<std::string, std::string> map_; | |
public: | |
Properties() {}; | |
Properties(std::initializer_list< std::initializer_list<std::string> > init) { | |
for (auto&& kv : init) { | |
if (kv.size() == 2) { | |
auto iter = kv.begin(); | |
auto& k = *iter++; | |
auto& v = *iter; | |
map_[k] = v; | |
} | |
} | |
} | |
template<class T> | |
void set(const std::string& key, const T& value) { | |
map_[key] = lexical_cast<std::string>(value); | |
} | |
void set(const std::string& key, const std::string& value) { | |
map_[key] = value; | |
} | |
opt<std::string> get(const std::string& key) const { | |
auto iter = map_.find(key); | |
if (iter != map_.end()) { | |
return iter->second; | |
} else { | |
return none; | |
} | |
} | |
#if 1 | |
DETAILS_GET_MEMBERS_BY_GET_GENERIC(int, getInt) | |
DETAILS_GET_MEMBERS_BY_GET_GENERIC(int64_t, getInt64) | |
DETAILS_GET_MEMBERS_BY_GET_GENERIC(float, getFloat) | |
DETAILS_GET_MEMBERS_BY_GET_GENERIC(double, getDouble) | |
#undef DETAILS_GET_MEMBERS_BY_GET_GENERIC | |
#else | |
opt<int> getInt(const std::string& key) const { | |
return getGeneric<int>(map_.at(key)); | |
} | |
opt<int64_t> getInt64(const std::string& key) const { | |
return getGeneric<int64_t>(map_.at(key)); | |
} | |
opt<float> getFloat(const std::string& key) const { | |
return getGeneric<float>(map_.at(key)); | |
} | |
opt<double> getDouble(const std::string& key) const { | |
return getGeneric<double>(map_.at(key)); | |
} | |
#endif | |
}; | |
} // namespace tell | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment