Garciat
2/23/2013 - 1:24 AM

main.cpp

#pragma once

#include "siterator.hpp"

#include <array>

namespace extra {
	using namespace siterator;

	template<typename T, size_t N, typename I = decltype(uint_iterator<0>())>
	struct to_bool_arr_helper {
		typedef I cur_iterator;

		template<typename J>
		struct iteration {
			typedef to_bool_arr_helper<T, N, J> type;
		};

		void operator ()(const T& val, std::array<bool, N> &arr) const {
			arr[N - I::type::value - 1] = (val & (1 << I::type::value)) != 0;
		}
	};

	template<typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type, typename N = std::integral_constant<size_t, 8 * sizeof(T)>>
	void to_bool_arr(const T& val, std::array<bool, N::value> &arr) {
		do_loop<to_bool_arr_helper<T, N::value>, static_iterator<N>>(val, arr);
	}

	template<typename T, size_t N, typename I = decltype(uint_iterator<0>())>
	struct arr_writer {
		typedef I cur_iterator;

		template<typename J>
		struct iteration {
			typedef arr_writer<T, N, J> type;
		};

		void operator ()(const std::array<T, N> &arr) const {
			std::cout << arr[I::type::value];
		}
	};

	template<typename T, size_t N>
	void do_arr_write(const std::array<T, N> &arr) {
		do_loop<arr_writer<T, N>, decltype(uint_iterator<N>())>(arr);
	}
}
#pragma once

#include <type_traits>

namespace siterator {
	template<typename T>
	struct static_iterator;

	template<typename T, T X>
	struct static_iterator<std::integral_constant<T, X>> {
		typedef std::integral_constant<T, X> type;

		typedef static_iterator<std::integral_constant<T, X + 1>> next;

		typedef static_iterator<std::integral_constant<T, X>> curr;

		typedef static_iterator<std::integral_constant<T, X - 1>> prev;

		template<typename U>
		struct equal : std::false_type { };

		template<typename U, U Y>
		struct equal<static_iterator<std::integral_constant<U, Y>>>
			: std::enable_if<std::is_same<T, U>::value, std::integral_constant<bool, X == Y>>::type { };
	};

	template<size_t K>
	static_iterator<std::integral_constant<size_t, K>> uint_iterator() { }

	template<typename Func, typename End, typename Cur, bool, typename... Params>
	struct static_loop_helper;

	template<typename Func, typename End, typename Cur, typename... Params>
	struct static_loop_helper<Func, End, Cur, true, Params...> {
		typedef typename Cur::next Next;
		typedef typename Func::template iteration<Cur>::type CurFunc;

		void operator()(Params&&... params) const {
			CurFunc()(std::forward<Params>(params)...);
			static_loop_helper<Func, End, Next, !Next::template equal<End>::value, Params...>()(std::forward<Params>(params)...);
		}
	};

	template<typename Func, typename End, typename Cur, typename... Params>
	struct static_loop_helper<Func, End, Cur, false, Params...> {
		void operator()(Params&&...) const {
			// end recursion
		}
	};

	template<typename Func, typename End, typename Cur = typename Func::cur_iterator, typename... Params>
	struct static_loop {
		void operator()(Params&&... params) const {
			static_loop_helper<Func, End, Cur, !Cur::template equal<End>::value, Params...>()(std::forward<Params>(params)...);
		}
	};

	template<typename Func, typename End, typename Cur = typename Func::cur_iterator, typename... Params>
	void do_loop(Params&&... params) {
		static_loop<Func, End, Cur, Params...>()(std::forward<Params>(params)...);
	}
}
#pragma once

#include "siterator.hpp"

namespace extra {
	using namespace siterator;

	template<typename Func>
	struct repeater {
		typedef decltype(uint_iterator<0>()) cur_iterator;

		template<typename J>
		struct iteration {
			typedef repeater<Func> type;
		};

		inline void operator ()(const Func &func) const {
			func();
		}
	};

	template<size_t N, typename Func>
	void repeat(const Func &func) {
		do_loop<repeater<Func>, decltype(uint_iterator<N>())>(func);
	}
}
#include "siterator.hpp"
#include "repeater.hpp"
#include "to_bool_arr.hpp"

#include <iostream>
#include <array>

int main() {
	using namespace siterator;
	using namespace extra;

	unsigned int val = 0xDEADBEEF;
	std::array<bool, 8 * sizeof val> arr;

	to_bool_arr(val, arr);

	do_arr_write(arr);
}