--- /dev/null
+add_library(bino INTERFACE)
+target_include_directories(bino INTERFACE include)
+
+if(NOT ENABLE_TEST)
+ return()
+endif(NOT ENABLE_TEST)
+
+# Google Test is mandatory for internal testing
+nncc_find_package(GTest REQUIRED)
+
+file(GLOB_RECURSE TESTS "tests/*.cpp")
+
+GTest_AddTest(bino_test ${TESTS})
+target_link_libraries(bino_test bino)
--- /dev/null
+# bino
+
+Let's manipulate std::pair values with UNIX pipe-like syntax.
+
+**NOTE** The _bino_ originates from a binocular telescope.
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#ifndef __BINO_H__
+#define __BINO_H__
+
+#include <utility>
+
+namespace bino
+{
+
+template <typename Callable> class UniformTransform
+{
+public:
+ UniformTransform(Callable &&cb) : f{std::forward<Callable>(cb)}
+ {
+ // DO NOTHING
+ }
+
+public:
+ template <typename T>
+ auto operator()(const std::pair<T, T> &p) const
+ -> decltype(std::make_pair(std::declval<Callable>()(p.first),
+ std::declval<Callable>()(p.second)))
+ {
+ return std::make_pair(f(p.first), f(p.second));
+ }
+
+private:
+ Callable f;
+};
+
+template <typename Callable> UniformTransform<Callable> transform_both(Callable &&f)
+{
+ return UniformTransform<Callable>{std::forward<Callable>(f)};
+}
+
+// TODO Implement transform_both(f, g)
+// TODO Implement transform_first(f)
+// TODO Implement transform_second(f)
+
+} // namespace bino
+
+template <typename T, typename U, typename Callable>
+auto operator|(const std::pair<T, U> &p, Callable &&f) -> decltype(f(p))
+{
+ return std::forward<Callable>(f)(p);
+}
+
+#endif // __BINO_H__
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/**
+ * Let's test functionals in "bino".
+ *
+ * NOTE The tests in this file assume that operator overloading works well.
+ */
+
+#include "bino.h"
+
+#include <gtest/gtest.h>
+
+TEST(FunctionalTests, transform_both_uniform)
+{
+ auto inc = [](int n) { return n + 1; };
+ auto res = std::make_pair(1, 3) | bino::transform_both(inc);
+
+ ASSERT_EQ(res.first, 2);
+ ASSERT_EQ(res.second, 4);
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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 "bino.h"
+
+#include <gtest/gtest.h>
+
+TEST(OperatorOverloadingTests, reduce_sum)
+{
+ auto pair = std::make_pair(1, 3);
+ auto reduce_sum = [](const std::pair<int, int> &p) { return p.first + p.second; };
+
+ ASSERT_EQ(pair | reduce_sum, 4);
+}