#include <iostream>
#include <cstdint>
#include <functional>

//めんどくさいので8ビットで・・・Orz
static const int Radix = 2;
static const int s0= 0;//not need??
static const int s1 = 1;
static const int s2 = s1*Radix;
static const int s3 = s2*Radix;
static const int s4 = s3*Radix;
static const int s5 = s4*Radix;
static const int s6 = s5*Radix;
static const int s7 = s6*Radix;
static const int s8 = s7*Radix;
static const int ShiftN[] = {s1, s2, s3, s4, s5, s6, s7, s8 };
static const int CharBit = 8;

std::uint8_t ShiftLeft(std::uint8_t N, int P){
	return N * ShiftN[P];
}
std::uint8_t ShiftRight(std::uint8_t N, int P){
	std::uint8_t A = N /ShiftN[P];
	return A;
}
std::uint8_t SnipeBit(std::uint8_t N, int P){
	std::uint8_t A = N%ShiftN[P];
	std::uint8_t B = ShiftRight(A,P-1);

	return B;
}
std::uint8_t SnipeBitWithPos(std::uint8_t N, int P){
	std::uint8_t A = SnipeBit(N, P);

	return ShiftLeft(A,P);
}

std::uint8_t TestAnd(std::uint8_t A, std::uint8_t B, int P){
	std::uint8_t AA = SnipeBit(A, P);
	std::uint8_t BB = SnipeBit(B, P);
	char R[] = { 0, 0, 1 };

	return R[AA + BB];
}

std::uint8_t TestOr(std::uint8_t A, std::uint8_t B, int P){
	std::uint8_t AA = SnipeBit(A, P);
	std::uint8_t BB = SnipeBit(B, P);
	char R[] = { 0, 1, 1 };

	return R[AA + BB];
}
std::uint8_t TestXor(std::uint8_t A, std::uint8_t B, int P){
	std::uint8_t AA = SnipeBit(A, P);
	std::uint8_t BB = SnipeBit(B, P);
	char R[] = { 0, 1, 0 };

	return R[AA + BB];

}
std::uint8_t TestNot(std::uint8_t A, int P){
	std::uint8_t AA = SnipeBit(A, P);
	char R[] = { 1, 0 };

	return R[AA];
}

std::uint8_t ConstructNumber(std::uint8_t A, std::uint8_t B, std::function<std::uint8_t(std::uint8_t, std::uint8_t, int)> F){

	std::uint8_t N = 0;
	int S=1;
	N += ShiftLeft(F(A, B, S), S-1); S++;
	N += ShiftLeft(F(A, B, S), S-1); S++;
	N += ShiftLeft(F(A, B, S), S-1); S++;
	N += ShiftLeft(F(A, B, S), S-1); S++;
	return N;

}

bool ShowBits(std::uint8_t N ,bool LF = true){
	for (int i = CharBit-1; i >= 0; i--)
	{
		std::cout << ((N>>i)&1);//表示関数だからいいよね？
	}
	if(LF == true) std::cout << std::endl;
	return true;
}

int main(){
	/** /
	ShowBits(0xff);
	ShowBits(0x7f);
	ShowBits(0x7e);
	ShowBits(ShiftRight(0xff, 5));
	ShowBits(0xff>>5);
	ShowBits(ShiftLeft(0xff, 5));
	ShowBits(0xff<<5);
	ShowBits(SnipeBit(0x8, 4));
	ShowBits(SnipeBit(0xff, 3));
	ShowBits(0xf7);
	ShowBits(SnipeBit(0xf7, 4));
	ShowBits(SnipeBitWithPos(0xf7, 4));
	ShowBits(SnipeBitWithPos(0xff, 4));
	std::cout << "---------------------"<<std::endl;
	/* */
	ShowBits(0xc,false);std::cout << " as Value A"<<std::endl;
	ShowBits(0xa,false);std::cout << " as Value B"<<std::endl;
	ShowBits(ConstructNumber(0xc, 0xa, TestAnd),false);std::cout << " as And"<<std::endl;
	ShowBits(ConstructNumber(0xc, 0xa, TestOr),false);std::cout << " as OR"<<std::endl;
	ShowBits(ConstructNumber(0xc, 0xa, TestXor),false);std::cout << " as Xor"<<std::endl;
	return 0;

}