1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
#include <iostream>
#include <string> // *** required
#include <vector>
#include <bitset>
int isNthBitSet (const unsigned char &c, int n) {
static unsigned char mask[] = {1, 2, 4, 8, 16, 32, 64, 128};
// c = 00000010 n= 1 ( rightmost bit is n=0, leftmost is n=7), result is 1
std::bitset<8> x(c);
std::cout << "This buffer " << x << std::endl;
return ((c & mask[n]) != 0);
}
void SetNthBit (unsigned char &c, int n) {
static unsigned char mask[] = {1, 2, 4, 8, 16, 32, 64, 128};
// c = 00000010 n= 1 ( rightmost bit is n=0, leftmost is n=7), result is 1
c=c | mask[n];
std::bitset<8> x(c);
std::cout << "New byte " << x << std::endl;
}
enum packet_type {
bool_type,
value_type
};
struct Sensor_packet {
Sensor_packet( std::string id, int size, packet_type ip_type ) : id(id), size(size), p_type(ip_type) {};
std::string id;
int size ;
packet_type p_type;
//virtual void dummy() const {}; //uncomment to allow dynamic_cast to work by establishing polymorphism, otherwise, static_cast works
};
struct Sensor_packet_b : public Sensor_packet {
int bit_offset=0;
unsigned char buffer=0x01; //hold the buffer to which a bit setting at bit_offset is checked to arrive at a boolean value
bool result=false;
Sensor_packet_b(std::string i_id, int ibit_offset=0) : Sensor_packet(i_id, 1 , packet_type::bool_type ), bit_offset(ibit_offset) {
std::bitset<8> x(buffer);
std::cout << "Initial buffer " << id << " "<< x << std::endl;
};
};
struct Sensor_packet_v : public Sensor_packet {
Sensor_packet_v(std::string i_id, int i_size ) : Sensor_packet(i_id, i_size, packet_type::value_type ){};
uint16_t buffer=0x02; //hold the int result for sensor packets that return a value such as distance, angle_turned
};
class Biscuit {
public:
int x;
Biscuit(){};
void setup_request(std::vector<Sensor_packet *> &spacket){ //eventually will build the serial packet request and write to serial device and then read from it
for (auto &s : spacket) {
if (s->p_type == packet_type::bool_type ) {
std::cout << s->id << " is a bool_type " << std::endl;
Sensor_packet_b * t= static_cast<Sensor_packet_b*>(s); //dynamic cast wont work, pointer is not polymorphic unless the virtual dummy method is used
// but static_cast seems to work
std::bitset<8> x(t->buffer);
std::cout << "Original buffer " << x << std::endl; //checking to see if the buffer value was carried over from initialization value
t->result=isNthBitSet(t->buffer,t->bit_offset);
}
else {
std::cout << s->id << " is a value_type " << std::endl;
Sensor_packet_v * t= static_cast<Sensor_packet_v*>(s);
std::bitset<8> x(t->buffer);
std::cout << "Original buffer " << x << std::endl;
t->buffer=20;
}
}
}
};
template <class T>
class wrapper{
public:
T* ptr;
wrapper(T &object){ ptr=&object; }; //create a wrapper object by taking a reference
~wrapper(){
std::cout << "wrapper destructor" << std::endl;
}
};
struct Robot {
template < wrapper<Sensor_packet>&... Sensor_packet_objects >
//template < wrapper<Sensor_packet>*... Sensor_packet_objects > //equivalent code when passing a pointer
int check_sensor( int = 0 ) {
std::vector< wrapper<Sensor_packet>*> l_list { std::addressof(Sensor_packet_objects)... } ;
//std::vector< wrapper<Sensor_packet>*> l_list { Sensor_packet_objects... } ; //equivalent code when passing a pointer
std::vector< Sensor_packet* > s_list;
//Convert to vector of Sensor_packet*
for (auto &p :l_list) {
s_list.push_back(p->ptr);
}
std::cout << "Size of vector of wrapper" << l_list.size() << std::endl;
for( auto &p : l_list ) std::cout << "id " << p->ptr->id << '\n' ;
std::cout << "Converted to vector of Sensor_packet" << std::endl;
for( auto &p : s_list ) std::cout << "id " << p->id << '\n' ;
engine.setup_request(s_list); //send the vector as a reference
std::cout << "Checking results" << std::endl;
for( auto &p : s_list ) {
if (p->p_type == bool_type) {
std::cout << p->id << " bool " << static_cast<Sensor_packet_b*>(p)->result << '\n' ;
} else
std::cout << p->id << " value " << static_cast<Sensor_packet_v*>(p)->buffer << '\n' ;
}
return true;
}
Biscuit engine;
};
Sensor_packet_b wheel( "WHEEL", 0 ); //id, bit_offset
Sensor_packet_v bumper( "BUMPER", 1 ); //id, buffer
// create a wrapper object using a Sensor_packet object
wrapper<Sensor_packet> wbumper(bumper); //value_type
wrapper<Sensor_packet> wwheel(wheel); //value_type
struct Behavior {
typedef int (Robot::*m_behavior) (int) ;
m_behavior behaviour ;
Robot& robot ;
Behavior( m_behavior mbhav, Robot& robot ) : behaviour(mbhav), robot(robot) {}
void exec() { (robot.*behaviour)(0) ; }
};
int main() {
Robot robot ;
Behavior behaviour( &Robot::check_sensor< wwheel, wbumper >, robot );
//Behavior behaviour( &Robot::check_sensor< &wwheel, &wbumper >, robot ); //equivalent code when passing pointers
behaviour.exec();
}
|