#pragma once
+#include "tuple-helper.hpp"
#include "type.hpp"
#include <string>
+#include <tuple>
#include <vector>
namespace vist {
namespace tsqb {
namespace internal {
-template<typename... Base>
-class ColumnPack {
+template<typename... Columns>
+class ColumnPack final {
public:
- virtual ~ColumnPack() = default;
+ using TableType = typename std::tuple_element<0, std::tuple<Columns...>>::type::TableType;
+ using TupleType = std::tuple<Columns...>;
- template<typename ColumnType>
- std::string getName(ColumnType&&) const noexcept { return std::string(); }
- std::vector<std::string> getNames(void) const noexcept { return {}; }
+ explicit ColumnPack(Columns&& ...columns) : columns(columns...)
+ {
+ }
- int size() const noexcept { return 0; }
-};
+ template<typename Column>
+ std::string getName(const Column& column) const noexcept
+ {
+ std::string name;
+ auto predicate = [&name, &column](const auto& iter) {
+ if (type::cast_compare(column, iter.type))
+ name = iter.name;
+ };
-template<typename Front, typename... Rest>
-class ColumnPack<Front, Rest...> : public ColumnPack<Rest...> {
-public:
- using Column = Front;
- using TableType = typename Column::TableType;
+ tuple_helper::for_each(this->columns, predicate);
- explicit ColumnPack(Front&& front, Rest&& ...rest);
- virtual ~ColumnPack() = default;
+ return name;
+ }
- ColumnPack(const ColumnPack&) = delete;
- ColumnPack& operator=(const ColumnPack&) = delete;
+ std::vector<std::string> getNames(void) const noexcept
+ {
+ std::vector<std::string> names;
+ auto closure = [&names](const auto& iter) {
+ names.push_back(iter.name);
+ };
- ColumnPack(ColumnPack&&) = default;
- ColumnPack& operator=(ColumnPack&&) = default;
+ tuple_helper::for_each(this->columns, closure);
- template<typename ColumnType>
- std::string getName(ColumnType&& type) const noexcept;
- std::vector<std::string> getNames(void) const noexcept;
+ return names;
+ }
- int size() const noexcept { return Base::size() + 1; }
+ std::size_t size() const noexcept
+ {
+ return std::tuple_size<TupleType>::value;
+ }
private:
- using Base = ColumnPack<Rest...>;
-
- Column column;
+ std::tuple<Columns...> columns;
};
-template<typename Front, typename... Rest>
-ColumnPack<Front, Rest...>::ColumnPack(Front&& front, Rest&& ...rest) :
- Base(std::forward<Rest>(rest)...), column(front)
-{
-}
-
-template<typename Front, typename... Rest>
-std::vector<std::string> ColumnPack<Front, Rest...>::getNames(void) const noexcept
-{
- auto names = Base::getNames();
- names.push_back(this->column.name);
-
- return std::move(names);
-}
-
-template<typename Front, typename... Rest>
-template<typename ColumnType>
-std::string ColumnPack<Front, Rest...>::getName(ColumnType&& type) const noexcept
-{
- if (type::cast_compare(column.type, std::forward<ColumnType>(type)))
- return column.name;
-
- return Base::template getName<ColumnType>(std::forward<ColumnType>(type));
-}
-
} // namespace internal
} // namespace tsqb
} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2020-present Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+#include <gtest/gtest.h>
+
+#include <vist/query-builder/column-pack.hpp>
+#include <vist/query-builder/column.hpp>
+
+using namespace vist::tsqb;
+using namespace vist::tsqb::internal;
+
+namespace {
+
+struct Sample {
+ int int1;
+ int int2;
+ std::string str1;
+ std::string str2;
+ bool bool1;
+ bool bool2;
+};
+
+ColumnPack columns { Column("int1", &Sample::int1),
+ Column("int2", &Sample::int2),
+ Column("str1", &Sample::str1),
+ Column("str2", &Sample::str2),
+ Column("bool1", &Sample::bool1),
+ Column("bool2", &Sample::bool2) };
+}
+
+TEST(ColumnTests, size)
+{
+ EXPECT_EQ(columns.size(), 6);
+}
+
+TEST(ColumnTests, get_name)
+{
+ EXPECT_EQ(columns.getName(&Sample::int1), "int1");
+ EXPECT_EQ(columns.getName(&Sample::int2), "int2");
+ EXPECT_EQ(columns.getName(&Sample::str1), "str1");
+ EXPECT_EQ(columns.getName(&Sample::str2), "str2");
+ EXPECT_EQ(columns.getName(&Sample::bool1), "bool1");
+ EXPECT_EQ(columns.getName(&Sample::bool2), "bool2");
+}
+
+TEST(ColumnTests, get_names)
+{
+ EXPECT_EQ(columns.getNames().size(), 6);
+}