diff --git a/Makefile b/Makefile index 71d762fe7f670e8f9ecab9225d8063a154673144..e0181271cdcdf38aa1efca0a73496eb07ba39cbf 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ lexer.yy.cc: lexer.l parser.tab.h flex -o lexer.yy.cc lexer.l parser: generate - g++ -o parser parser.tab.cc lexer.yy.cc + g++ -I. -o parser parser.tab.cc lexer.yy.cc clean: rm -f parser parser.tab.cc lexer.yy.cc parser.tab.h diff --git a/parser.y b/parser.y index 07077b0da1e63848c74e3672df7e6b02138c2c37..3952b964c2cac99dfc60466f1ef97ab42f7329a7 100644 --- a/parser.y +++ b/parser.y @@ -1,7 +1,7 @@ %{ #include <string> -#include <rlib/stdio.hpp> +#include <rlib.min.hpp> #include <cassert> #include <cstdlib> diff --git a/rlib.min.hpp b/rlib.min.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9e5f288877ab2e3377664f231fc27566b103a059 --- /dev/null +++ b/rlib.min.hpp @@ -0,0 +1,164 @@ +/* + * + * string.hpp: string process utility. + * Recolic Keghart <root@recolic.net> + * MIT License + * + * Bensong Liu: This is my "nickname" and this lib is written by me. I want to use 'split string' function. + * + */ + +#ifndef R_STRING_HPP +#define R_STRING_HPP + +#include <vector> +#include <string> +#include <stdexcept> + +namespace rlib { + class string : public std::string { + public: + using std::string::string; + string() : std::string() {} + string(const std::string &s) : std::string(s) {} + string(std::string &&s) : std::string(std::forward<std::string>(s)) {} + + private: + template <typename T> struct as_helper {}; + template <typename T> + T as(as_helper<T>) const { + if(empty()) return T(); + return T(*this); + } + std::string as(as_helper<std::string>) const { + return std::move(*this); + } + rlib::string as(as_helper<rlib::string>) const { + return std::move(*this); + } + char as(as_helper<char>) const { + if(size() > 1) + throw std::invalid_argument("Can not convert rlib::string to char: size() > 1."); + return size() == 0 ? '\0' : *cbegin(); + } + unsigned char as(as_helper<unsigned char>) const { + return static_cast<unsigned char>(as<char>()); + } + bool as(as_helper<bool>) const { + if(*this == "true") { + return true; + } + else if(*this == "false") { + return false; + } + // Nothing is slower than throw(); Just test more cases... + else if(*this == "1" || *this == "True" || *this == "TRUE") { + return true; + } + else if(*this == "0" || *this == "False" || *this == "FALSE") { + return false; + } + throw std::invalid_argument("Can not convert rlib::string to bool. Not matching any template."); + } + +#define RLIB_IMPL_GEN_AS_NUMERIC(type, std_conv) \ + type as(as_helper<type>) const { \ + if(empty()) return 0; \ + return std::std_conv(*this); \ + } + + RLIB_IMPL_GEN_AS_NUMERIC(int, stoi) + RLIB_IMPL_GEN_AS_NUMERIC(long, stol) + RLIB_IMPL_GEN_AS_NUMERIC(unsigned long, stoul) + RLIB_IMPL_GEN_AS_NUMERIC(unsigned long long, stoull) + RLIB_IMPL_GEN_AS_NUMERIC(long long, stoll) + RLIB_IMPL_GEN_AS_NUMERIC(float, stof) + RLIB_IMPL_GEN_AS_NUMERIC(double, stod) + RLIB_IMPL_GEN_AS_NUMERIC(long double, stold) + +#define RLIB_IMPL_GEN_AS_ALIAS(new_type, old_type) \ + new_type as(as_helper<new_type>) const { \ + return static_cast<new_type>(as<old_type>()); \ + } + + RLIB_IMPL_GEN_AS_ALIAS(unsigned int, unsigned long) + RLIB_IMPL_GEN_AS_ALIAS(unsigned short, unsigned long) + //RLIB_IMPL_GEN_AS_ALIAS(uint8_t, unsigned long) + + RLIB_IMPL_GEN_AS_ALIAS(short, int) + //RLIB_IMPL_GEN_AS_ALIAS(int8_t, int) + + public: + template <typename T> + T as() const { + return std::forward<T>(as(as_helper<T>())); + } + + template <typename T> + std::vector<T> split_as(const char ÷r = ' ') const { + const string &toSplit = *this; + std::vector<T> buf; + size_t curr = 0, prev = 0; + while((curr = toSplit.find(divider, curr)) != std::string::npos) { + buf.push_back(string(toSplit.substr(prev, curr - prev)).as<T>()); + ++curr; // skip divider + prev = curr; + } + buf.push_back(string(toSplit.substr(prev)).as<T>()); + return std::move(buf); + } + template <typename T> + std::vector<T> split_as(const std::string ÷r) const { + const string &toSplit = *this; + std::vector<T> buf; + size_t curr = 0, prev = 0; + while((curr = toSplit.find(divider, curr)) != std::string::npos) { + buf.push_back(string(toSplit.substr(prev, curr - prev)).as<T>()); + curr += divider.size(); // skip divider + prev = curr; + } + buf.push_back(string(toSplit.substr(prev)).as<T>()); + return std::move(buf); + } + + }; +} + +#endif + +#include <iostream> +#include <string> + +namespace rlib { + // This is my own hand-written library. I'm making it easy to use it directly. + + inline rlib::string scanln(std::istream &is = std::cin, char delimiter = '\n') noexcept { + std::string line; + std::getline(is, line, delimiter); + return (line); // RVO + } + + template <typename PrintFinalT> + void print(PrintFinalT reqArg) + { + std::cout << reqArg; + } + template <typename Required, typename... Optional> + void print(Required reqArgs, Optional... optiArgs) + { + std::cout << reqArgs << ' '; + print(optiArgs ...); + } + template <typename... Optional> + void println(Optional... optiArgs) + { + print(optiArgs ...); + println(); + } + template <> + inline void println() + { + //std::cout << rlib::endl; + std::cout << std::endl; + } +}