tuple_for
tupleã®è¦ç´ ãé ã«å¦çãããå ´åã«ãã©ãããã®ãç°¡åãªã®ãæ©ã¾ããã
ã¡ã¢æ¸ããããã«ãã¹ããã¦ãªãã§ãã
#include <tuple> #include <type_traits> #include <utility> template <int L, int R, int S, std::size_t... Indices> constexpr auto tuple_for_impl() { if constexpr (L + sizeof...(Indices) >= R) { return [&](auto&& t, auto&& fn) constexpr { if constexpr (std::tuple_size_v<std::remove_reference_t<decltype(t)>> > 0 && std::is_same_v<decltype(fn(std::get<0>(t))), void>) { return [](auto...) constexpr {return std::tuple<>{}; }((fn(std::get<Indices>(t)), 0)...); } else { return std::make_tuple(fn(std::get<Indices>(t))...); } }; } else { return tuple_for_impl<L, R, S, Indices..., L + S * sizeof...(Indices)>(); } } template <int L, int R, int S = 1, std::size_t... Indices> constexpr auto tuple_for = tuple_for_impl<L, R, S, Indices...>(); int main() { constexpr auto t = std::make_tuple(0, 'a', 0.1); constexpr auto r = tuple_for<0, 3>(t, [](const auto& arg) { return arg + 1; }); static_assert(std::get<0>(r) == 1); static_assert(std::get<1>(r) == 'b'); static_assert(std::get<2>(r) == 1.1); }
tuple_elementåè
using type_impl<Indices, Types>::value...;ããã½ã
#include <type_traits> #include <utility> extern void* enabler; template <typename T> struct identity { using type = T; }; template <std::size_t N, typename T> struct type_impl { template <std::size_t I, std::enable_if_t<I == N>*& = enabler> static T value(); }; template <typename... Types> struct tuple_impl; template <std::size_t... Indices, typename... Types> struct tuple_impl<std::index_sequence<Indices...>, Types...> : type_impl<Indices, Types>... { using type_impl<Indices, Types>::value...; template <std::size_t I> using type = typename decltype(tuple_impl<std::index_sequence<Indices...>, Types...>::template value<I>())::type; }; template <typename... Types> struct tuple : tuple_impl<std::make_index_sequence<sizeof...(Types)>, identity<Types>...> {}; template <std::size_t N, typename T> struct tuple_element { using type = typename T::template type<N>; }; template <std::size_t N, typename T> using tuple_element_t = typename tuple_element<N, T>::type; int main() { using t = tuple<const int, char*, void>; static_assert(std::is_same_v<const int, tuple_element_t<0, t>>); static_assert(std::is_same_v<char*, tuple_element_t<1, t>>); static_assert(std::is_same_v<void, tuple_element_t<2, t>>); }
æ¸ãåã
constexpr lambdaã使ããã£ã¦ãã¨ã¯ï¼ã¨ãããã¨ã§æãã¤ãããã¿ãã ã¨ããããclangããã§ã¯åãã¦ãã¾ã£ããgccããã¯ç½®ãã¦ãã¼ãã§ãã wandbox.org
proof of conceptãªã®ã§ãå¿ è¦ãªãªã¼ãã¼ãã¼ãå ¨ç¶ãªãã£ããåæã«constã¤ãããããæ°ãããã®ã§æ³¨æã
#include <iostream> #include <utility> static constexpr auto stack = [](auto... xs) constexpr { return [=](auto access) { return access(xs...); }; }; template <std::size_t N> struct popper {}; template <typename Type> struct helper { Type data; template <typename T> static constexpr auto make_helper(T&& arg) { return helper<std::decay_t<T>>(std::forward<T>(arg)); } static constexpr auto push = [](auto xs, auto x) constexpr { return xs([=](auto... z) { return [=](auto access) { return access(x, z...); }; }); }; static constexpr auto pop = [](auto xs) constexpr { return xs([=](auto, auto... z) { return [=](auto access) { return access(z...); }; }); }; template <typename T> constexpr helper(T&& arg) : data(std::forward<T>(arg)) {}; template <typename U> constexpr auto operator +(const U& rhs) const { return helper<Type>::make_helper(push(this->data, rhs.data)); } template <typename U> constexpr auto operator -(const U&) const { return helper<Type>::make_helper(pop(this->data)); } }; static constexpr auto top = [](auto xs) constexpr { return xs.data([=](auto v, auto...) { return v; }); }; template <typename T> static constexpr auto make_helper(T&& arg) { return helper<std::decay_t<T>>(std::forward<T>(arg)); } template <typename... Types> struct tuple { decltype((make_helper(stack()) + ... + make_helper(std::declval<Types>()))) data; template <typename... Ts> constexpr tuple(Ts&&... args) : data((make_helper(stack()) + ... + make_helper(std::forward<Ts&&>(args)))) {} }; template <typename... Types, std::size_t... Indices> constexpr auto get_impl(const tuple<Types...>& t, std::index_sequence<Indices...>) { return (t.data - ... - make_helper(popper<Indices>{})); } template <std::size_t N, typename... Types> constexpr auto get(const tuple<Types...>& t) { static_assert(sizeof...(Types) > 0); return top(get_impl(t, std::make_index_sequence<(sizeof...(Types) - 1) - N>{})); } int main() { constexpr tuple<int, char, double, bool> t(1, 'a', 3.14, true); static_assert(get<0>(t) == 1); static_assert(get<1>(t) == 'a'); static_assert(get<2>(t) == 3.14); static_assert(get<3>(t) == true); }
å ¥ãåã«ããã°N^2åã«å±é
#include <iostream> template <typename... Ts> int f(Ts... i) { int k = 0; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-value" (... , (i, (... , (++k, i)))); #pragma GCC diagnostic pop return k; } int main() { std::cout << f(0) << std::endl; std::cout << f(0, 0) << std::endl; std::cout << f(0, 0, 0) << std::endl; std::cout << f(0, 0, 0, 0) << std::endl; std::cout << f(0, 0, 0, 0, 0) << std::endl; }
1
4
9
16
25
Folding-expressionãç¨ãã¦parameter packé·ã®index_sequenceãæ§ç¯ãã
å帰深度ãO(1)ã«æããããï¼(è¶£å³)
#include <type_traits> template <int... Ns> struct V; template <int N, int... Ns> struct V<N, Ns...> { template <int M> V<N + 1, N, Ns...> operator +(V<M>); }; template <> struct V<> { template <int M> V<0> operator +(V<M>); }; template <typename... Types> struct S { template <int... Indices> static V<(sizeof...(Indices) - Indices - 1)...> reverse(V<Indices...>); template <typename> struct dummy {}; using type = decltype(reverse((V<>{} + ... + V<sizeof(dummy<Types>)>{}))); }; struct T; int main() { static_assert(std::is_same<V<0, 1, 2, 3, 4>, typename S<T, T, T, T, T>::type>::value); }
Traktor + Max/Jitterã§æ¥½æ²ã«åãããæ åã®ãã³åºããèªååãã
è¦ç´
[èæ¯]
- ã¯ã©ãã§ã¯æ¥½æ²ã«åããã¦VJãããæ åãåºãã¦ããã
[ç®ç]
- ä¸äººã§ããã¡DJãããéã«ãã¢ãã½ã³ã«ã¯OPåç»ããã¥ã¼ã¸ãã¯ã¯ãªããã¨ãã£ãæ åãåºããã
[ææ¡]
- Traktorã®broadcastçµç±ã§æ¥½æ²æ å ±ãæã£ã¦ãã¦Max/Jitterã§æ åãåºã
[çµè«]
- åºæ¥ããã©ï¼åçä¸ã®æ¥½æ²æ å ±ã®ç²¾åº¦ãè¯ããªã
Traktorã®broadcastããæ å ±ãæã£ã¦ãã¦Max / jitterã§æ åã®ãã³åºããèªååããããããçµãã ï¼Traktorã®play countã®æ§è³ªä¸ï¼æ²ã®åãæ¿ããå¤å®æ å ±ã®è³ªãå¾®å¦ãªã®ã§éã³ç¨éï¼ pic.twitter.com/ExUFnstP8J
— Ararik (@houbunsya) August 17, 2016
詳細
Traktorã«ã¯ç´æ¥ã«åçä¸ã®æ¥½æ²æ å ±ãåçæéãåããéçºè åãã®APIãï¼ãã©ã°ã¤ã³ãæ¸ãããã®SDKãä»ã®ã¨ãããªãï¼ãããï¼broadcastingæ©è½ãããï¼æ¥½æ²åãã¢ã¼ãã£ã¹ãåãªã©ããªãéå®çãªæ å ±ã®ã¿ã§ããã°jsonå½¢å¼ã§åå¾åºæ¥ããããªã®ã§ãããç¨ããï¼
Traktorã®broadcastingã¯icecast streaming protocolã§é ä¿¡ãããã®ã§ï¼icecastã®ãµã¼ããç«ã¦ãï¼ Macã§ããã°brewã使ãã°ç°¡åã«å ¥ãï¼
$ brew install icecast
configãã¡ã¤ã«å ã®hackmeã¨ãªã£ã¦ããåæãã¹ã¯ã¼ãã夿´ããï¼
$ vim /usr/local/etc/icecast.xml
ãµã¼ãã®ç«ã¡ä¸ã
$ icecast -c /usr/local/etc/icecast.xml
Traktorã®broadcastingè¨å®ãè¡ãï¼ä¸è¨ã¯è¨å®ä¾ï¼Passwordã¯å ç¨è¨å®ãããã®ãå ¥åããï¼

è¨å®å¾ï¼Broadcastingãæå¹ã«ããã«ã¯ç»é¢å³ä¸ã®ã¢ã³ãããã¼ã¯ãæ¼ãï¼ã¢ã³ãããã¼ã¯ãç¹æ» ããå ´åï¼icecastãµã¼ããç«ã¡ä¸ãã£ã¦ããªããè¨å®ã«èª¤ããããï¼

ã¢ã³ãããç¹ç¯ããç¶æ ã§æ¥½æ²ãåçããã¨ï¼127.0.0.1:8000/status-json.xslã«ã¢ã¯ã»ã¹ãããã¨ã§jsonå½¢å¼ã§æ¥½æ²æ å ±ãåå¾åºæ¥ãï¼
æå¾ã«Maxãããã®å®è£ ï¼ãã¼ã«ã«ãµã¼ãããjsonãã¡ã¤ã«ãåå¾ãã¦ï¼æ¥½æ²æ å ±ããã¼ã¹ãé©åãªæ åãåçãããããã使ããï¼
ããã¾ããªè§£èª¬ãããã¨ï¼Maxã§ã¯æ¨æºã§maxurlã¨ããcurlã®ã©ãããªãã¸ã§ã¯ãã使ããã®ã§ãã¼ã¿ã®åå¾ã¯é常ã«ç°¡åã«åºæ¥ãï¼jsonã®ãã¼ã¹ã¯jsãªãã¸ã§ã¯ãã使ãã°javascriptã使ããã®ã§JSON.parseã§æ¸ãï¼æ¥½æ²ã¿ã¤ãã«ã¨åçãã¹ãåç»ã®ãã¹ã®å¯¾å¿è¡¨ãç¨æãã¦ããï¼ä¸å®ééã§jsonãã¡ã¤ã«ã®ãã¼ãªã³ã°ãè¡ãï¼åçä¸ã®æ¥½æ²ã«å¤æ´ãããã°jit.qt.movieã«èªã¿è¾¼ãã¹ãåç»ãã¡ã¤ã«ã®ãã¹ãæ¸¡ãæ åãåãæ¿ããï¼
maxpatã½ã¼ã¹ã³ã¼ã (ãã¡ã¤ã«ã®ãã¹ãªã©ã¯é©å®ä¿®æ£ãå¿ è¦) autovj.js · GitHub

åçå¤å®ã®èª¿æ´
Mixã®ããã«æ¬¡ã®æ²ãè£ã§åçãã¦ããã¨ï¼ãã¡ããåçããã¦ããã¨ã¿ãªããã¦æã«åãã¦åç»ãåãæ¿ãã£ã¦ãã¾ããã¨ãããï¼ Traktorã®åçå¤å®ã¯ï¼Preferences -> Transportå ã®Play Countã®å¤ãåçæéãä¸åã£ããåçã¨ã¿ãªãï¼ã¨ããä»çµã¿ããã10ç§ãªã©çãè¨å®ãã¦ããã¨ãã®ãããªãã¨ãèµ·ããããï¼
次ã®è¨äºãªã©ãåèã«Play Countã大ããã«è¨å®ããã¨å°ããã·ã«ãªãï¼ Traktor 再生済みチェックの条件を設定 | Ambient Music for Life
ã¨ã¯ãããã¯ãåçå¤å®ã®åé¡ã¯æ ¹æ¬çã«ã¯è§£æ±ºããªããï¼ä»åº¦ã¯æ åã®åãæ¿ããã¿ã¤ãã³ã°ãé ããªããã¡ã«â¦ï¼
æè©®ããã¡ã§éã¶ãããªã®ã§ããã§ãè¯ãããã©ï¼çé¢ç®ã«èªååãããªãåçä¸ã®é³ãã¼ã¿ãç´æ¥åã£ã¦ãã¦ç´æ¥æå ã§æ¥½æ²å¤å®ãããæ¹ãè¯ãããï¼
coutã§å¤æ¬¡å é åã®dump
ä½ãã®å½¹ã«ç«ã¤ãã
å®è¡çµæ http://melpon.org/wandbox/permlink/MJN1EGWMw1ixnvBJ
#include <iostream> template <typename T, std::size_t N> std::ostream& operator<< (std::ostream& os, const T(&arr)[N]) { os << '{'; std::size_t i = 0; for (const auto& v : arr) { os << v; if (++i != N) { os << ',' << ' '; } } os << '}'; return os; } int main() { int arr[][2][6] = {{{0, 1, 2, 3, 4, 5}, {0, 1, 2, 3, 4, 5}}, {{0, 1, 2, 3, 4, 5}, {0, 1, 2, 3, 4, 5}}}; std::cout << arr << std::endl; }
åºå
{{{0, 1, 2, 3, 4, 5}, {0, 1, 2, 3, 4, 5}}, {{0, 1, 2, 3, 4, 5}, {0, 1, 2, 3, 4, 5}}}