FAILED: obj/third_party/angle/angle_common/mathutil.obj ... ../../3rdparty/chromium/third_party/angle/src/common/mathutil.cpp(75): error C4244: '=': conversion from 'double' to 'float', possible loss of data ../../3rdparty/chromium/third_party/angle/src/common/mathutil.cpp(77): error C4244: '=': conversion from 'double' to 'float', possible loss of data ../../3rdparty/chromium/third_party/angle/src/common/mathutil.cpp(79): error C4244: '=': conversion from 'double' to 'float', possible loss of data
tokenizer<std::string> tk(data); auto start = std::chrono::high_resolution_clock::now(); while (tk.more()) { tk(' '); }
auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration<double> diff = end - start; std::cout << "elapsed time = " << diff.count(); }
template <classTag> structinsert_impl { template <classR, classU, classB, classI, classE> structapply_impl { using inner = typename push_back<R, typename deref<I>::type>::type; using type = typename apply_impl<inner, U, B, typename next<I>::type, E>::type; };
template <classR, classU, classI, classE> structapply_impl<R, U, I, I, E> { using inner = typename push_back<R, U>::type; using inner2 = typename push_back<inner, typename deref<I>::type>::type; using type = typename apply_impl<inner2, I, U, typename next<I>::type, E>::type; };
template <classR, classU, classB, classE> structapply_impl<R, U, B, E, E> { using type = R; };
template <classR, classU, classE> structapply_impl<R, U, E, E, E> { using type = typename push_back<R, U>::type; };
template <classT, classB, classU> structapply { using init = typename clear<T>::type; using type = typename apply_impl<init, U, B, typename begin<T>::type, typename end<T>::type>::type; }; };
template <classR, classU, classB, classI, classE> structapply_impl { using inner = typename push_back<R, typename deref<I>::type>::type; using type = typename apply_impl<inner, U, B, typename next<I>::type, E>::type; };
该元函数非常简单,通过push_back将原序列的元素插入到新序列中,其中I是迭代器。
template <classR, classU, classI, classE> structapply_impl<R, U, I, I, E> { using inner = typename push_back<R, U>::type; using inner2 = typename push_back<inner, typename deref<I>::type>::type; using type = typename apply_impl<inner2, I, U, typename next<I>::type, E>::type; };
template <classR, classU, classB, classE> structapply_impl<R, U, B, E, E> { using type = R; };
template <classR, classU, classE> structapply_impl<R, U, E, E, E> { using type = typename push_back<R, U>::type; };
最后两个特化版本的apply_impl限定了元函数的结束条件。一方面apply_impl<R, U, B, E, E>,当原序列遍历到结束迭代器时,如果插入目标位置不是结束迭代器,则插入操作直接结束,返回新序列。另一方面apply_impl<R, U, E, E, E>,当原序列遍历到结束迭代器时,如果插入目标位置正好是结束迭代器,那么就将目标元素U插入到新序列的末尾。
以下是一个调用insert元函数的示例:
using insert_list = list<int, bool, char>; using result_list = insert<insert_list, short, begin<insert_list>::type>::type;
template <template <class...> classT, classN, classU, classB, class... Args> structapply<iterator<T<U, Args...>, N, B>> { using type = U; };
template <template <class...> classT, classN, classB> structapply<iterator<T<>, N, B>> { using type = none; }; };
deref_impl和next_impl一样也是针对迭代器的元函数,它对迭代器进行解引用操作,随后可以获得元素本身。观察deref_impl的内嵌apply元函数,它也有两个特化版本。当其实参的迭代器为iterator<T<U, Args...>, N, B>时,说明它不是最后一个迭代器,于是返回当前元素U。当实参的迭代器为iterator<T<>, N, B>时,说明这是最后一个迭代器,它不包含任何元素,所以返回none。这里的none是YAMPL专门为类似这种情况定义的类型,用来表示没有意义的结果,具体定义如下:
structnone_tag {}; structnone { using tag = none_tag; };