Commit 80717685 by Maarten L. Hekkelman

better row_handle::get

parent 71c8541b
...@@ -60,7 +60,7 @@ namespace detail ...@@ -60,7 +60,7 @@ namespace detail
template <typename... Ts, std::size_t... Is> template <typename... Ts, std::size_t... Is>
std::tuple<Ts...> get(std::index_sequence<Is...>) const std::tuple<Ts...> get(std::index_sequence<Is...>) const
{ {
return std::tuple<Ts...>{m_row[m_columns[Is]].template as<Ts>()...}; return std::tuple<Ts...>{ m_row[m_columns[Is]].template as<Ts>()... };
} }
const row_handle &m_row; const row_handle &m_row;
...@@ -185,21 +185,33 @@ class row_handle ...@@ -185,21 +185,33 @@ class row_handle
return item_handle(get_column_ix(column_name), const_cast<row_handle &>(*this)); return item_handle(get_column_ix(column_name), const_cast<row_handle &>(*this));
} }
template <typename... Ts, size_t N> // template <typename... Ts, size_t N>
std::tuple<Ts...> get(char const *const (&columns)[N]) const // std::tuple<Ts...> get(char const *const (&columns)[N]) const
{ // {
static_assert(sizeof...(Ts) == N, "Number of columns should be equal to number of types to return"); // static_assert(sizeof...(Ts) == N, "Number of columns should be equal to number of types to return");
std::array<size_t, N> cix; // std::array<size_t, N> cix;
for (size_t i = 0; i < N; ++i) // for (size_t i = 0; i < N; ++i)
cix[i] = get_column_ix(columns[i]); // cix[i] = get_column_ix(columns[i]);
return detail::get_row_result<Ts...>(*this, std::move(cix)); // return detail::get_row_result<Ts...>(*this, std::move(cix));
} // }
template <typename... C> template <typename... C>
auto get(C... columns) const auto get(C... columns) const
{ {
return detail::get_row_result<C...>(*this, {get_column_ix(columns)...}); return detail::get_row_result<C...>(*this, { get_column_ix(columns)... });
}
template <typename... Ts, typename... C, std::enable_if_t<sizeof...(Ts) == sizeof...(C), int> = 0>
std::tuple<Ts...> get(C... columns) const
{
return detail::get_row_result<Ts...>(*this, { get_column_ix(columns)... });
}
template<typename T>
T get(const char *column)
{
return operator[](get_column_ix(column)).template as<T>();
} }
void assign(const std::vector<item> &values) void assign(const std::vector<item> &values)
...@@ -224,7 +236,7 @@ class row_handle ...@@ -224,7 +236,7 @@ class row_handle
uint16_t add_column(std::string_view name); uint16_t add_column(std::string_view name);
operator row*() operator row *()
{ {
return m_row; return m_row;
} }
...@@ -252,7 +264,9 @@ class row_initializer ...@@ -252,7 +264,9 @@ class row_initializer
row_initializer &operator=(row_initializer &&) = default; row_initializer &operator=(row_initializer &&) = default;
row_initializer(std::initializer_list<item> items) row_initializer(std::initializer_list<item> items)
: m_items(items) {} : m_items(items)
{
}
template <typename ItemIter, std::enable_if_t<std::is_same_v<typename ItemIter::value_type, item>, int> = 0> template <typename ItemIter, std::enable_if_t<std::is_same_v<typename ItemIter::value_type, item>, int> = 0>
row_initializer(ItemIter b, ItemIter e) row_initializer(ItemIter b, ItemIter e)
......
...@@ -193,8 +193,7 @@ class dictionary_parser : public parser ...@@ -193,8 +193,7 @@ class dictionary_parser : public parser
if (isCategorySaveFrame) if (isCategorySaveFrame)
{ {
std::string category; std::string category = dict["category"].front().get<std::string>("id");
cif::tie(category) = dict["category"].front().get("id");
std::vector<std::string> keys; std::vector<std::string> keys;
for (auto k : dict["category_key"]) for (auto k : dict["category_key"])
...@@ -204,13 +203,12 @@ class dictionary_parser : public parser ...@@ -204,13 +203,12 @@ class dictionary_parser : public parser
for (auto g : dict["category_group"]) for (auto g : dict["category_group"])
groups.insert(g["id"].as<std::string>()); groups.insert(g["id"].as<std::string>());
mCategoryValidators.push_back(category_validator{category, keys, groups}); mCategoryValidators.push_back(category_validator{ category, keys, groups });
} }
else else
{ {
// if the type code is missing, this must be a pointer, just skip it // if the type code is missing, this must be a pointer, just skip it
std::string typeCode; std::string typeCode = dict["item_type"].front().get<std::string>("code");
cif::tie(typeCode) = dict["item_type"].front().get("code");
const type_validator *tv = nullptr; const type_validator *tv = nullptr;
if (not(typeCode.empty() or typeCode == "?")) if (not(typeCode.empty() or typeCode == "?"))
...@@ -220,8 +218,7 @@ class dictionary_parser : public parser ...@@ -220,8 +218,7 @@ class dictionary_parser : public parser
for (auto e : dict["item_enumeration"]) for (auto e : dict["item_enumeration"])
ess.insert(e["value"].as<std::string>()); ess.insert(e["value"].as<std::string>());
std::string defaultValue; std::string defaultValue = dict["item_default"].front().get<std::string>("value");
cif::tie(defaultValue) = dict["item_default"].front().get("value");
bool defaultIsNull = false; bool defaultIsNull = false;
if (defaultValue.empty()) if (defaultValue.empty())
{ {
...@@ -237,25 +234,24 @@ class dictionary_parser : public parser ...@@ -237,25 +234,24 @@ class dictionary_parser : public parser
for (auto i : dict["item"]) for (auto i : dict["item"])
{ {
std::string tagName, category, mandatory; std::string tagName, category, mandatory;
cif::tie(tagName, category, mandatory) = i.get("name", "category_id", "mandatory_code"); cif::tie(tagName, category, mandatory) = i.get("name", "category_id", "mandatory_code");
std::string catName, item_name; std::string cat_name, item_name;
std::tie(catName, item_name) = split_tag_name(tagName); std::tie(cat_name, item_name) = split_tag_name(tagName);
if (catName.empty() or item_name.empty()) if (cat_name.empty() or item_name.empty())
error("Invalid tag name in _item.name " + tagName); error("Invalid tag name in _item.name " + tagName);
if (not iequals(category, catName) and not(category.empty() or category == "?")) if (not iequals(category, cat_name) and not(category.empty() or category == "?"))
error("specified category id does match the implicit category name for tag '" + tagName + '\''); error("specified category id does match the implicit category name for tag '" + tagName + '\'');
else else
category = catName; category = cat_name;
auto &ivs = mItemValidators[category]; auto &ivs = mItemValidators[category];
auto vi = find(ivs.begin(), ivs.end(), item_validator{item_name}); auto vi = find(ivs.begin(), ivs.end(), item_validator{ item_name });
if (vi == ivs.end()) if (vi == ivs.end())
ivs.push_back(item_validator{item_name, iequals(mandatory, "yes"), tv, ess, defaultValue, defaultIsNull}); ivs.push_back(item_validator{ item_name, iequals(mandatory, "yes"), tv, ess, defaultValue, defaultIsNull });
else else
{ {
// need to update the itemValidator? // need to update the itemValidator?
...@@ -295,11 +291,7 @@ class dictionary_parser : public parser ...@@ -295,11 +291,7 @@ class dictionary_parser : public parser
// collect the dict from our dataBlock and construct validators // collect the dict from our dataBlock and construct validators
for (auto i : dict["item_linked"]) for (auto i : dict["item_linked"])
{ {
std::string childTagName, parentTagName; mLinkedItems.emplace(i.get<std::string,std::string>("child_name", "parent_name"));
cif::tie(childTagName, parentTagName) = i.get("child_name", "parent_name");
mLinkedItems.emplace(childTagName, parentTagName);
} }
} }
} }
...@@ -357,7 +349,7 @@ class dictionary_parser : public parser ...@@ -357,7 +349,7 @@ class dictionary_parser : public parser
if (piv == nullptr) if (piv == nullptr)
error("in pdbx_item_linked_group_list, item '" + parent + "' is not specified"); error("in pdbx_item_linked_group_list, item '" + parent + "' is not specified");
key_type key{piv->m_category->m_name, civ->m_category->m_name, link_group_id}; key_type key{ piv->m_category->m_name, civ->m_category->m_name, link_group_id };
if (not linkIndex.count(key)) if (not linkIndex.count(key))
{ {
linkIndex[key] = linkKeys.size(); linkIndex[key] = linkKeys.size();
...@@ -385,7 +377,7 @@ class dictionary_parser : public parser ...@@ -385,7 +377,7 @@ class dictionary_parser : public parser
if (piv == nullptr) if (piv == nullptr)
error("in pdbx_item_linked_group_list, item '" + parent + "' is not specified"); error("in pdbx_item_linked_group_list, item '" + parent + "' is not specified");
key_type key{piv->m_category->m_name, civ->m_category->m_name, 0}; key_type key{ piv->m_category->m_name, civ->m_category->m_name, 0 };
if (not linkIndex.count(key)) if (not linkIndex.count(key))
{ {
linkIndex[key] = linkKeys.size(); linkIndex[key] = linkKeys.size();
...@@ -450,7 +442,8 @@ class dictionary_parser : public parser ...@@ -450,7 +442,8 @@ class dictionary_parser : public parser
try try
{ {
type_validator v = { type_validator v = {
code, map_to_primitive_type(primitiveCode), construct}; code, map_to_primitive_type(primitiveCode), construct
};
m_validator.add_type_validator(std::move(v)); m_validator.add_type_validator(std::move(v));
} }
......
...@@ -85,8 +85,7 @@ void file::load_dictionary() ...@@ -85,8 +85,7 @@ void file::load_dictionary()
auto *audit_conform = front().get("audit_conform"); auto *audit_conform = front().get("audit_conform");
if (audit_conform and not audit_conform->empty()) if (audit_conform and not audit_conform->empty())
{ {
std::string name; std::string name = audit_conform->front().get<std::string>("dict_name");
cif::tie(name) = audit_conform->front().get("dict_name");
if (not name.empty()) if (not name.empty())
{ {
......
...@@ -166,6 +166,26 @@ BOOST_AUTO_TEST_CASE(r_1) ...@@ -166,6 +166,26 @@ BOOST_AUTO_TEST_CASE(r_1)
BOOST_CHECK_EQUAL(row["f-1"].compare(1), 0); BOOST_CHECK_EQUAL(row["f-1"].compare(1), 0);
BOOST_CHECK_EQUAL(row["f-2"].compare("two"), 0); BOOST_CHECK_EQUAL(row["f-2"].compare("two"), 0);
BOOST_CHECK_EQUAL(row["f-3"].compare(3.0), 0); // This fails when running in valgrind... sigh BOOST_CHECK_EQUAL(row["f-3"].compare(3.0), 0); // This fails when running in valgrind... sigh
const auto &[f1, f2, f3] = row.get<int,std::string,float>("f-1", "f-2", "f-3");
BOOST_CHECK_EQUAL(f1, 1);
BOOST_CHECK_EQUAL(f2, "two");
BOOST_CHECK_EQUAL(f3, 3.0); // This fails when running in valgrind... sigh
BOOST_CHECK_EQUAL(row.get<int>("f-1"), 1);
BOOST_CHECK_EQUAL(row.get<std::string>("f-2"), "two");
BOOST_CHECK_EQUAL(row.get<float>("f-3"), 3.0);
int f_1;
std::string f_2;
float f_3;
cif::tie(f_1, f_2, f_3) = row.get("f-1", "f-2", "f-3");
BOOST_CHECK_EQUAL(f_1, 1);
BOOST_CHECK_EQUAL(f_2, "two");
BOOST_CHECK_EQUAL(f_3, 3.0); // This fails when running in valgrind... sigh
} }
BOOST_AUTO_TEST_CASE(r_2) BOOST_AUTO_TEST_CASE(r_2)
...@@ -1442,21 +1462,21 @@ _test.name ...@@ -1442,21 +1462,21 @@ _test.name
for (auto r : db["test"].find(cif::key("id") == 1)) for (auto r : db["test"].find(cif::key("id") == 1))
{ {
const auto &[id, name] = r.get<int, std::string>({"id", "name"}); const auto &[id, name] = r.get<int, std::string>("id", "name");
BOOST_CHECK_EQUAL(id, 1); BOOST_CHECK_EQUAL(id, 1);
BOOST_CHECK_EQUAL(name, "aap"); BOOST_CHECK_EQUAL(name, "aap");
} }
for (auto r : db["test"].find(cif::key("id") == 4)) for (auto r : db["test"].find(cif::key("id") == 4))
{ {
const auto &[id, name] = r.get<int, std::string>({"id", "name"}); const auto &[id, name] = r.get<int, std::string>("id", "name");
BOOST_CHECK_EQUAL(id, 4); BOOST_CHECK_EQUAL(id, 4);
BOOST_CHECK(name.empty()); BOOST_CHECK(name.empty());
} }
for (auto r : db["test"].find(cif::key("id") == 5)) for (auto r : db["test"].find(cif::key("id") == 5))
{ {
const auto &[id, name] = r.get<int, std::string>({"id", "name"}); const auto &[id, name] = r.get<int, std::string>("id", "name");
BOOST_CHECK_EQUAL(id, 5); BOOST_CHECK_EQUAL(id, 5);
BOOST_CHECK(name.empty()); BOOST_CHECK(name.empty());
} }
...@@ -1465,7 +1485,7 @@ _test.name ...@@ -1465,7 +1485,7 @@ _test.name
for (auto r : db["test"]) for (auto r : db["test"])
{ {
const auto &[id, name] = r.get<int, std::optional<std::string>>({"id", "name"}); const auto &[id, name] = r.get<int, std::optional<std::string>>("id", "name");
switch (id) switch (id)
{ {
case 1: BOOST_CHECK(name == "aap"); break; case 1: BOOST_CHECK(name == "aap"); break;
...@@ -2041,7 +2061,7 @@ _test.text ?? ...@@ -2041,7 +2061,7 @@ _test.text ??
for (auto r : test1) for (auto r : test1)
{ {
const auto &[text] = r.get<std::string>({"text"}); auto text = r.get<std::string>("text");
BOOST_CHECK_EQUAL(text, "??"); BOOST_CHECK_EQUAL(text, "??");
} }
...@@ -2057,7 +2077,7 @@ _test.text ?? ...@@ -2057,7 +2077,7 @@ _test.text ??
for (auto r : test2) for (auto r : test2)
{ {
const auto &[text] = r.get<std::string>({"text"}); auto text = r.get<std::string>("text");
BOOST_CHECK_EQUAL(text, "??"); BOOST_CHECK_EQUAL(text, "??");
} }
} }
...@@ -2094,7 +2114,7 @@ boo.data_.whatever ...@@ -2094,7 +2114,7 @@ boo.data_.whatever
size_t i = 0; size_t i = 0;
for (auto r : test1) for (auto r : test1)
{ {
const auto &[text] = r.get<std::string>({"text"}); auto text = r.get<std::string>("text");
BOOST_CHECK_EQUAL(text, kS[i].s); BOOST_CHECK_EQUAL(text, kS[i].s);
BOOST_CHECK_EQUAL(cif::sac_parser::is_unquoted_string(kS[i].s), kS[i].q); BOOST_CHECK_EQUAL(cif::sac_parser::is_unquoted_string(kS[i].s), kS[i].q);
++i; ++i;
...@@ -2113,7 +2133,7 @@ boo.data_.whatever ...@@ -2113,7 +2133,7 @@ boo.data_.whatever
i = 0; i = 0;
for (auto r : test2) for (auto r : test2)
{ {
const auto &[text] = r.get<std::string>({"text"}); auto text = r.get<std::string>("text");
BOOST_CHECK_EQUAL(text, kS[i++].s); BOOST_CHECK_EQUAL(text, kS[i++].s);
} }
} }
...@@ -2148,7 +2168,7 @@ There it was!)", false} ...@@ -2148,7 +2168,7 @@ There it was!)", false}
size_t i = 0; size_t i = 0;
for (auto r : test1) for (auto r : test1)
{ {
const auto &[text] = r.get<std::string>({"text"}); auto text = r.get<std::string>("text");
BOOST_CHECK_EQUAL(text, kS[i].s); BOOST_CHECK_EQUAL(text, kS[i].s);
BOOST_CHECK_EQUAL(cif::sac_parser::is_unquoted_string(kS[i].s), kS[i].q); BOOST_CHECK_EQUAL(cif::sac_parser::is_unquoted_string(kS[i].s), kS[i].q);
++i; ++i;
...@@ -2167,7 +2187,7 @@ There it was!)", false} ...@@ -2167,7 +2187,7 @@ There it was!)", false}
i = 0; i = 0;
for (auto r : test2) for (auto r : test2)
{ {
const auto &[text] = r.get<std::string>({"text"}); auto text = r.get<std::string>("text");
BOOST_CHECK_EQUAL(text, kS[i++].s); BOOST_CHECK_EQUAL(text, kS[i++].s);
} }
} }
...@@ -2564,8 +2584,6 @@ _cat_1.name ...@@ -2564,8 +2584,6 @@ _cat_1.name
std::stringstream ss; std::stringstream ss;
ss << f; ss << f;
std::cout << f << std::endl;
cif::file f2(ss); cif::file f2(ss);
f2.set_validator(&validator); f2.set_validator(&validator);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment