C++ 杂项工具函数收集

这里其中的许多函数都不是我自己写的,而是抄的。

天下代码一大抄嘛。

 

1. 给定一个整数,计算向上最接近的2的N次方

 1 uint32_t next_pow2(uint32_t v) 
 2 {
 3     --v;
 4     v |= v >> 1;
 5     v |= v >> 2;
 6     v |= v >> 4;
 7     v |= v >> 8;
 8     v |= v >> 16;
 9     return ++v;
10 }

 

2.给定一个32bit整数,计算它的二进制中出现了几次1

1 uint32_t bitcount2(uint32_t v) 
2 {
3     v = v - ((v >> 1) & 0x55555555);
4     v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
5     v = (v + (v >> 4)) & 0x0F0F0F0F;
6     v = v + (v >> 8);
7     v = v + (v >> 16);
8     return v & 0x0000003F;
9 }

    上面代码是下面的简洁版

1 uint32_t bitcount2_2(uint32_t v) 
2 {
3     v = (v & 0x55555555) + ((v >> 1) & 0x55555555);
4     v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
5     v = (v & 0x0F0F0F0F) + ((v >> 4) & 0x0F0F0F0F);
6     v = (v & 0x00FF00FF) + ((v >> 8) & 0x00FF00FF);
7     v = (v & 0x0000FFFF) + ((v >> 16) & 0x0000FFFF);
8     return v;
9 }

  原理是将一个32bit数分隔成16个2bit数,开始计算每个2bit中含有多少个1:

    因为0x55=0b01010101,则有:

      a.   0b01 & 0b01 = 1;

      b.   0b01 & 0b00 = 0;

      c.   0b01 & 0b10  = 0;0b01 & (0b10>>1)  = 1;0 + 1 = 1;

      d.   0b01 & 0b11  = 1;0b01 & (0b11>>1)  = 1;1 + 1 = 2;

  以下同理,只是分割粒度的不同,用分治的方法进行计算。

 

3.给定一个字符串,计算其hash值

 1 constexpr unsigned int ELFHash(const char *str)
 2 {
 3     unsigned int hash = 0, 
 4                  x = 0;
 5     while (*str)
 6     {
 7         hash = (hash << 4) + (*str++);
 8         if ((x = hash & 0xF0000000L) != 0)
 9         {
10             hash ^= (x >> 24);
11             hash &= ~x;
12         }
13     }
14     return (hash & 0x7FFFFFFF);
15 }

 

4. 给定一变量名,获得其变量名的字符串

1 #define ___S(s) #s
2 #define __S(s) ___S(s)

 

5. 线程池

  1 #include <mutex>
  2 #include <condition_variable>
  3 #include <functional>
  4 #include <queue>
  5 #include <thread>
  6 
  7 namespace LC
  8 {
  9 
 10 #ifdef _WIN32
 11     #include "windows.h"
 12 #else
 13     #include <unistd.h>
 14 #endif
 15 
 16 #ifdef _WIN32
 17     SYSTEM_INFO sysInfo;
 18     GetSystemInfo( &sysInfo );
 19     #define logicCoreCount sysInfo.dwNumberOfProcessors
 20 #else
 21     #define logicCoreCount sysconf(_SC_NPROCESSORS_ONLN)
 22 #endif
 23 
 24 
 25 class thread_pool 
 26 {
 27 public:
 28     explicit thread_pool(size_t thread_count) 
 29     {
 30         init(thread_count);
 31     }
 32 
 33     thread_pool() = default;
 34     thread_pool(thread_pool&&) = default;
 35 
 36     ~thread_pool() 
 37     {
 38         exit();
 39     }
 40 
 41     void init(size_t th_cnt)
 42     {
 43         data_ = std::make_shared<data>();
 44         
 45         for (size_t i = 0; i < th_cnt; ++i) 
 46         {
 47             std::thread([data = data_] {
 48                 std::unique_lock<std::mutex> lk(data->mtx_);
 49                 for (;;) 
 50                 {
 51                     if (!data->tasks_.empty()) 
 52                     {
 53                         //从队列中取出一个任务执行
 54                         auto current = std::move(data->tasks_.front());
 55                         data->tasks_.pop();
 56 
 57                         lk.unlock();
 58                         current();
 59                         lk.lock();
 60                     } 
 61                     else if (data->is_shutdown_) 
 62                         break;
 63                     else
 64                         data->cond_.wait(lk);
 65                 }
 66             }).detach();
 67         }
 68     }
 69 
 70     template <class F>
 71     void execute(F&& task) 
 72     {
 73         {
 74             std::lock_guard<std::mutex> lk(data_->mtx_);
 75             data_->tasks_.emplace(std::forward<F>(task));
 76         }
 77         data_->cond_.notify_one();
 78     }
 79 
 80     void exit()
 81     {
 82         if ((bool) data_) 
 83         {
 84             {
 85                 std::lock_guard<std::mutex> lk(data_->mtx_);
 86                 data_->is_shutdown_ = true;
 87             }
 88             data_->cond_.notify_all();
 89         }
 90     }
 91 private:
 92     struct data 
 93     {
 94         std::mutex mtx_;
 95         std::condition_variable cond_;
 96         bool is_shutdown_ = false;
 97         std::queue<std::function<void()>> tasks_;
 98     };
 99     std::shared_ptr<data> data_;
100 };
101 
102 };

 

6. 计算可变参数宏的参数包中的参数个数

 1 #define GET_NTH_ARG(                                                                        \
 2     _1,  _2,  _3,  _4,  _5,  _6,  _7,  _8,  _9,  _10, _11, _12, _13, _14, _15, _16, n, ...) n
 3 
 4 /**
 5  * @brief If We want to call GET_ARG_COUNT(a, s, d), and the GET_NTH_ARG is 
 6  *      GET_NTH_ARG(a, s, d, 16, 15, ..., 5, 4, 3(n), 2, 1), so GET_ARG_COUNT(a, s, d) return 3.
 7  * 
 8  * @notice: It's not work in VC++.
 9  */
10 #define GET_ARG_COUNT(...) GET_NTH_ARG(__VA_ARGS__,                 \
11     16, 15, 14, 13, 12, 11, 10, 9,  8,  7,  6,  5,  4,  3,  2,  1)

 

7. Excel 列名(字母)转数字(这个是我瞎鸡儿写的)

 1 int Colume2Num(const std::string& str)
 2 {
 3     if (str.empty())
 4         return -1;
 5 
 6     int sum = 0;
 7     for (int i = 0, n = str.size() - 1; i < str.size(); ++i, --n)
 8     {
 9         char ch = str.at(i);
10         if (ch < 'A' || ch > 'Z')
11             return -1;
12         int a = (ch - 'A' + 1);
13         sum += a * std::pow((double)26, (double)n);
14     }
15     return sum - 1;
16 }

 

8. 质量很低的伪随机数

1 //生成(-1, 1)的小数,来自perlin noise
2 double random1(int x)
3 {
4     x = (x << 13) ^ x;
5     return (1.0 - ((x * (x * x * 15731 + 789221) + 1376312589) & 0x7FFFFFFF) / 1073741824.0);
6     //如果要整数,那么就把其中的两个小数干掉,返回值为int
7     //        return ((x * (x * x * 15731 + 789221) + 1376312589) & 0x7FFFFFFF);
8 }

 

9. 质量更低的伪随机数(这个也是我瞎鸡儿写的;可以将a, b参数作为种子)

1 const int a = 49939;    //只要我频率设置得够大,就没人能发现这其实是一个sin
2 const int b = 773;
3 int64_t r = (std::sin(a * x + b) + 1) * (INT64_MAX >> 1);

 

10. 判断类中是否存在某成员函数(这个是我瞎鸡儿写的 x 3)(垃圾玩应也就能看看没法用)(这垃圾英语水平也没法看)

 1 #define __IS_HAVE_FUNC_DEF(fc) \
 2     template<typename T>\
 3     class is_has_method_##fc\
 4     {\
 5     public:\
 6         struct __size2 { char c[2]; };\
 7 \
 8     public:\
 9         template<typename C>\
10         static __size2 __is(...);\
11 \
12         template<typename C>\
13         static char __is(decltype(&C::fc));\
14 \
15         enum { value = (sizeof(__is<T>(0)) == sizeof(char)) };\
16     };\
17 \
18 
19 #define __IS_HAVE_FUNC(T, fc) is_has_method_##fc<T>::value;
20 
21 __IS_HAVE_FUNC_DEF(show2)
22 __IS_HAVE_FUNC_DEF(show3)
23 
24 class test 
25 {
26 public:
27     int show2() { return 0; }
28 };
29 
30 int main()
31 {
32     bool isHave = __IS_HAVE_FUNC(test, show3);
33     return 0;
34 }

 

11. 两个时间戳是否是同一天

1 constexpr time_t HOUR_S = 60 * 60;
2 constexpr time_t DAY_S = 24 * HOUR_S;
3 constexpr int TIME_ZONE = +8;
4 bool is_same_day(time_t time_A_s, time_t time_B_s, const int64_t offset_s)
5 {
6     time_A_s = time_A_s + ((TIME_ZONE * HOUR_S) - offset_s);
7     time_B_s = time_B_s + ((TIME_ZONE * HOUR_S) - offset_s);
8     return (time_A_s / DAY_S) == (time_B_s / DAY_S);
9 }
offset_s 默认为0, 表示过了几点才算1天。例如offset_s=HOUR_S*5,表示过了5点算一天。

12. 从一个参数包中,获取第N个参数的类型(c++17)
 1     template<usize_t i_, typename t_, typename ... ts_> 
 2     struct get_type 
 3         : public get_type<i_ - 1, ts_...>
 4     {
 5     };
 6 
 7     template<typename t_, typename ... ts_> 
 8     struct get_type<0, t_, ts_...>
 9     {
10         using type = t_;
11     };    

 

posted on 2021-07-02 16:32  __Even  阅读(179)  评论(0编辑  收藏  举报

导航