#pragma once // OpenCL SDK includes #include "OpenCLSDKCpp_Export.h" #include // OpenCL Utils includes #include // TCLAP includes #include // STL includes #include // std::shared_ptr, std::make_shared #include // std::make_tuple #include // std::vector namespace cl { namespace sdk { template auto parse(); template Option comprehend(Parsers... parsers); namespace detail { template auto comprehend_helper(std::tuple parser) { return util::detail::apply(comprehend, parser); } } template std::tuple parse_cli(int argc, char* argv[], std::string banner = "OpenCL SDK sample template") { TCLAP::CmdLine cli(banner); auto parsers = std::make_tuple(std::make_pair(Options{}, parse())...); util::detail::for_each_in_tuple(parsers, [&](auto&& parser) { util::detail::for_each_in_tuple( parser.second, [&](auto&& arg) { cli.add(arg.get()); }); }); cli.parse(argc, argv); return util::detail::transform_tuple(parsers, [](auto&& parser) { return detail::comprehend_helper< std::remove_reference_t>(parser.second); }); } } } // SDK built-in CLI parsers SDKCPP_EXPORT extern std::unique_ptr> valid_dev_constraint; namespace cl { namespace sdk { template <> inline auto parse() { return std::make_tuple( std::make_shared( "v", "verbose", "Extra informational output", false), std::make_shared( "q", "quiet", "Suppress standard output", false)); } template <> inline options::Diagnostic comprehend( std::shared_ptr verbose_arg, std::shared_ptr quiet_arg) { return options::Diagnostic{ verbose_arg->getValue(), quiet_arg->getValue() }; } template <> inline auto parse() { std::vector valid_dev_strings{ "all", "cpu", "gpu", "acc", "cus", "def" }; valid_dev_constraint = std::make_unique>( valid_dev_strings); return std::make_tuple(std::make_shared>( "p", "platform", "Index of platform to use", false, 0, "positive integral"), std::make_shared>( "d", "device", "Index of device to use", false, 0, "positive integral"), std::make_shared>( "t", "type", "Type of device to use", false, "def", valid_dev_constraint.get())); } template <> inline options::SingleDevice comprehend( std::shared_ptr> platform_arg, std::shared_ptr> device_arg, std::shared_ptr> type_arg) { auto device_type = [](std::string in) -> cl_device_type { if (in == "all") return CL_DEVICE_TYPE_ALL; else if (in == "cpu") return CL_DEVICE_TYPE_CPU; else if (in == "gpu") return CL_DEVICE_TYPE_GPU; else if (in == "acc") return CL_DEVICE_TYPE_ACCELERATOR; else if (in == "cus") return CL_DEVICE_TYPE_CUSTOM; else if (in == "def") return CL_DEVICE_TYPE_DEFAULT; else throw std::logic_error{ "Unkown device type after cli parse." }; }; return options::SingleDevice{ platform_arg->getValue(), device_arg->getValue(), device_type(type_arg->getValue()) }; } template <> inline auto parse() { return std::make_tuple( std::make_shared>("x", "width", "Width of window", false, 800, "positive integral"), std::make_shared>("y", "height", "Height of window", false, 800, "positive integral"), std::make_shared("f", "fullscreen", "Fullscreen window", false)); } template <> inline options::Window comprehend( std::shared_ptr> width_arg, std::shared_ptr> height_arg, std::shared_ptr fullscreen_arg) { return options::Window{ width_arg->getValue(), height_arg->getValue(), fullscreen_arg->getValue() }; } } }