diff --git a/01-Templet/21-SetMapTemplet/.gitkeep b/01-Templet/21-SetMapTemplet/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/01-Templet/21-SetMapTemplet/Makefile b/01-Templet/21-SetMapTemplet/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3bb62ef504d1e1e024a674c27b7baa49acb192af --- /dev/null +++ b/01-Templet/21-SetMapTemplet/Makefile @@ -0,0 +1,51 @@ +CC := g++ + +#注意每行后面不要有空格,否则会算到目录名里面,导致问题 +SRC_DIR = ./ +BUILD_DIR = tmp +OBJ_DIR = $(BUILD_DIR)/obj +DEPS_DIR = $(BUILD_DIR)/deps + +#这里添加其他头文件路径 +INC_DIR = \ + -I./include \ + -I./src \ + +#这里添加编译参数 +CC_FLAGS := $(INC_DIR) -g -std=c++17 +LNK_FLAGS := \ + -L/usr/local/lib + +#这里递归遍历3级子目录 +DIRS := $(shell find $(SRC_DIR) -maxdepth 3 -type d) + +#将每个子目录添加到搜索路径 +VPATH = $(DIRS) + +#查找src_dir下面包含子目录的所有cpp文件 +#SOURCES = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cpp)) +SOURCES = SdoTst.cpp +OBJS = $(addprefix $(OBJ_DIR)/,$(patsubst %.cpp,%.o,$(notdir $(SOURCES)))) +DEPS = $(addprefix $(DEPS_DIR)/, $(patsubst %.cpp,%.d,$(notdir $(SOURCES)))) +TARGET := $(patsubst %.cpp, %, $(SOURCES)) + + +$(TARGET):$(OBJS) + $(CC) $^ $(LNK_FLAGS) -o $@ +#编译之前要创建OBJ目录,确保目录存在 +$(OBJ_DIR)/%.o:%.cpp + if [ ! -d $(OBJ_DIR) ]; then mkdir -p $(OBJ_DIR); fi;\ + $(CC) -c $(CC_FLAGS) -o $@ $< +#编译之前要创建DEPS目录,确保目录存在 +#前面加@表示隐藏命令的执行打印 +$(DEPS_DIR)/%.d:%.cpp + @if [ ! -d $(DEPS_DIR) ]; then mkdir -p $(DEPS_DIR); fi;\ + set -e; rm -f $@;\ + $(CC) -MM $(CC_FLAGS) $< > $@.$$$$;\ + sed 's,\($*\)\.o[ :]*,$(OBJ_DIR)/\1.o $@ : ,g' < $@.$$$$ > $@;\ + rm -f $@.$$$$ +#前面加-表示忽略错误 +-include $(DEPS) +.PHONY : clean +clean: + rm -rf $(BUILD_DIR) $(TARGET) diff --git a/01-Templet/21-SetMapTemplet/Sdo.h b/01-Templet/21-SetMapTemplet/Sdo.h new file mode 100644 index 0000000000000000000000000000000000000000..fb443d717593598e9b46518e5c3e35936d4db435 --- /dev/null +++ b/01-Templet/21-SetMapTemplet/Sdo.h @@ -0,0 +1,49 @@ +/* DataList - template parameter should be like x0, x1, x2, x3... + * compare v against each x, to check if list contains or not contains v + * + * Usage: + * using DL = DataList<3, 6, 8, 19>; + * auto contains = DL::Contains(3); // contains = true + * auto contains = DL::Contains(4); // contains = flase + */ +constexpr size_t MAX_DATA_LIST = 32; +template +struct DataList { + static_assert(sizeof...(vs) <= MAX_DATA_LIST, "DataList too much, use std::set instead"); + template + constexpr static bool Contains(T val) + { + return ((val == vs) || ...); + } + + template + constexpr static bool NotContains(T val) + { + return !Contains(val); + } +}; + +/* DataPairs - template parameter should be like x0, y0, x1, y1, x2, y2, ..., z + * if v matches one of x, return corresponding y, else return z as default + * + * Usage: + * using DP = DataPairs<1, 10, 2, 20, 0>; + * auto v = DP::ValueOf(1); // v == 10 + * auto w = DP::ValueOf(3); // w == 0 + */ +constexpr size_t MAX_DATA_PAIRS = 16; +template +struct DataPairs { + static_assert(sizeof...(vs) %2 == 0, "DataPairs must be odd, and >= 3"); + static_assert(sizeof...(vs) < MAX_DATA_PAIRS * 2, "DataPairs too much, use std::map instead"); + + template + constexpr static auto ValueOf(T val) + { + if constexpr (sizeof...(vs) == 0) { + return val == x ? y : z; + } else { + return val == x ? y : DataPairs::ValueOf(val); + } + } +}; diff --git a/01-Templet/21-SetMapTemplet/SdoTst.cpp b/01-Templet/21-SetMapTemplet/SdoTst.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5061415164939c0492e474ce168813fd3c7e8f6c --- /dev/null +++ b/01-Templet/21-SetMapTemplet/SdoTst.cpp @@ -0,0 +1,24 @@ +#include +#include "Sdo.h" + +using namespace std; +using DL = DataList<3, 6, 8, 19>; +using DP = DataPairs<1, 10, 2, 20, 0>; + +int main() +{ + auto containsIs1 = DL::Contains(3); // contains = true + auto containsIs2 = DL::Contains(4); // contains = flase + cout << containsIs1 << endl; + cout << containsIs2 << endl; + + auto v = DP::ValueOf(1); // v == 10 + cout << "v = " << v << endl; + auto w = DP::ValueOf(3); // w == 0 + cout << "w = " << w << endl; + auto x = DP::ValueOf(2); // x == 20 + cout << "x = " << x << endl; + + return 0; +} +