Commit 80717685 by Maarten L. Hekkelman

better row_handle::get

parent 71c8541b
......@@ -60,7 +60,7 @@ namespace detail
template <typename... Ts, std::size_t... Is>
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;
......@@ -185,21 +185,33 @@ class row_handle
return item_handle(get_column_ix(column_name), const_cast<row_handle &>(*this));
}
template <typename... Ts, size_t N>
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");
// template <typename... Ts, size_t N>
// 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");
std::array<size_t, N> cix;
for (size_t i = 0; i < N; ++i)
cix[i] = get_column_ix(columns[i]);
return detail::get_row_result<Ts...>(*this, std::move(cix));
}
// std::array<size_t, N> cix;
// for (size_t i = 0; i < N; ++i)
// cix[i] = get_column_ix(columns[i]);
// return detail::get_row_result<Ts...>(*this, std::move(cix));
// }
template <typename... C>
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)
......@@ -224,7 +236,7 @@ class row_handle
uint16_t add_column(std::string_view name);
operator row*()
operator row *()
{
return m_row;
}
......@@ -252,7 +264,9 @@ class row_initializer
row_initializer &operator=(row_initializer &&) = default;
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>
row_initializer(ItemIter b, ItemIter e)
......
......@@ -193,8 +193,7 @@ class dictionary_parser : public parser
if (isCategorySaveFrame)
{
std::string category;
cif::tie(category) = dict["category"].front().get("id");
std::string category = dict["category"].front().get<std::string>("id");
std::vector<std::string> keys;
for (auto k : dict["category_key"])
......@@ -204,13 +203,12 @@ class dictionary_parser : public parser
for (auto g : dict["category_group"])
groups.insert(g["id"].as<std::string>());
mCategoryValidators.push_back(category_validator{category, keys, groups});
mCategoryValidators.push_back(category_validator{ category, keys, groups });
}
else
{
// if the type code is missing, this must be a pointer, just skip it
std::string typeCode;
cif::tie(typeCode) = dict["item_type"].front().get("code");
std::string typeCode = dict["item_type"].front().get<std::string>("code");
const type_validator *tv = nullptr;
if (not(typeCode.empty() or typeCode == "?"))
......@@ -220,8 +218,7 @@ class dictionary_parser : public parser
for (auto e : dict["item_enumeration"])
ess.insert(e["value"].as<std::string>());
std::string defaultValue;
cif::tie(defaultValue) = dict["item_default"].front().get("value");
std::string defaultValue = dict["item_default"].front().get<std::string>("value");
bool defaultIsNull = false;
if (defaultValue.empty())
{
......@@ -237,25 +234,24 @@ class dictionary_parser : public parser
for (auto i : dict["item"])
{
std::string tagName, category, mandatory;
cif::tie(tagName, category, mandatory) = i.get("name", "category_id", "mandatory_code");
std::string catName, item_name;
std::tie(catName, item_name) = split_tag_name(tagName);
std::string cat_name, item_name;
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);
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 + '\'');
else
category = catName;
category = cat_name;
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())
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
{
// need to update the itemValidator?
......@@ -295,11 +291,7 @@ class dictionary_parser : public parser
// collect the dict from our dataBlock and construct validators
for (auto i : dict["item_linked"])
{
std::string childTagName, parentTagName;
cif::tie(childTagName, parentTagName) = i.get("child_name", "parent_name");
mLinkedItems.emplace(childTagName, parentTagName);
mLinkedItems.emplace(i.get<std::string,std::string>("child_name", "parent_name"));
}
}
}
......@@ -357,7 +349,7 @@ class dictionary_parser : public parser
if (piv == nullptr)
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))
{
linkIndex[key] = linkKeys.size();
......@@ -385,7 +377,7 @@ class dictionary_parser : public parser
if (piv == nullptr)
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))
{
linkIndex[key] = linkKeys.size();
......@@ -450,7 +442,8 @@ class dictionary_parser : public parser
try
{
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));
}
......
......@@ -85,8 +85,7 @@ void file::load_dictionary()
auto *audit_conform = front().get("audit_conform");
if (audit_conform and not audit_conform->empty())
{
std::string name;
cif::tie(name) = audit_conform->front().get("dict_name");
std::string name = audit_conform->front().get<std::string>("dict_name");
if (not name.empty())
{
......
......@@ -166,6 +166,26 @@ BOOST_AUTO_TEST_CASE(r_1)
BOOST_CHECK_EQUAL(row["f-1"].compare(1), 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
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)
......@@ -1442,21 +1462,21 @@ _test.name
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(name, "aap");
}
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(name.empty());
}
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(name.empty());
}
......@@ -1465,7 +1485,7 @@ _test.name
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)
{
case 1: BOOST_CHECK(name == "aap"); break;
......@@ -2041,7 +2061,7 @@ _test.text ??
for (auto r : test1)
{
const auto &[text] = r.get<std::string>({"text"});
auto text = r.get<std::string>("text");
BOOST_CHECK_EQUAL(text, "??");
}
......@@ -2057,7 +2077,7 @@ _test.text ??
for (auto r : test2)
{
const auto &[text] = r.get<std::string>({"text"});
auto text = r.get<std::string>("text");
BOOST_CHECK_EQUAL(text, "??");
}
}
......@@ -2094,7 +2114,7 @@ boo.data_.whatever
size_t i = 0;
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(cif::sac_parser::is_unquoted_string(kS[i].s), kS[i].q);
++i;
......@@ -2113,7 +2133,7 @@ boo.data_.whatever
i = 0;
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);
}
}
......@@ -2148,7 +2168,7 @@ There it was!)", false}
size_t i = 0;
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(cif::sac_parser::is_unquoted_string(kS[i].s), kS[i].q);
++i;
......@@ -2167,7 +2187,7 @@ There it was!)", false}
i = 0;
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);
}
}
......@@ -2564,8 +2584,6 @@ _cat_1.name
std::stringstream ss;
ss << f;
std::cout << f << std::endl;
cif::file f2(ss);
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