C++ STL set with custom comparator - stl

For a C++ STL set I need a custom compare, but there is something seriously wrong with my code. Using Visual Studio 2019, it fails to compile. The first error is (in xutility) "error C2672: 'operator __surrogate_func': no matching overloaded function found".
Here is the code:
#include <set>
struct P
{
char a;
char b;
char c;
};
class PSortingCriterion
{
public:
bool operator() (const P &p1, const P &p2) const
{
if(p1.a != p2.a)
return p1.a < p2.a;
else if(p1.b != p2.b)
return p1.b < p2.b;
else if(p1.c != p2.c)
return p1.c < p2.c;
else
return false; // p1 == p2
}
};
std::set<P, PSortingCriterion> s1, s2, diff;
void F(void)
{
if(s1 != s2) // errors are all due to this statement; no errors if it's removed
{
}
}
Update: Following Igor Tandetnik's suggestion, I have modified the code, but it still doesn't compile (same error as above).
New code:
#include <set>
#include <algorithm>
#include <iterator>
struct P
{
char a;
char b;
char c;
};
class PSortingCriterion
{
public:
bool operator() (const P &p1, const P &p2) const
{
if(p1.a != p2.a)
return p1.a < p2.a;
else if(p1.b != p2.b)
return p1.b < p2.b;
else if(p1.c != p2.c)
return p1.c < p2.c;
else
return false; // p1 == p2
}
};
std::set<P, PSortingCriterion> s1, s2, diff;
void F(void)
{
set_difference(s1.begin(), s1.end(), s2.begin(), s2.end(), inserter(diff, diff.begin()));
}

To compare two sets, you compare the elements. See CppReference. But you haven't provided any way of comparing two objects of type P for equality.
if you add:
bool operator== (const P& p1, const P& p2) {
return p1.a == p2.a && p1.b == p2.b && p1.c == p2.c;
}
Then your code will compile.

Here's a simple example of overloading == and != operators (which is what you're trying to do I think?)
#include<set>
#include<iostream>
struct P {
char a;
char b;
char c;
bool operator==(const P &p2) const {
return this->a == p2.a && this->b == p2.b && this->c == p2.c;
}
bool operator!=(const P &p2) const {
return this->a != p2.a || this->b != p2.b || this->c != p2.c;
}
};
void EqualExample(void) {
P s1;
s1.a = 'a';
s1.b = 'b';
s1.c = 'c';
P s2;
s2.a = 'a';
s2.b = 'b';
s2.c = 'c';
if(s1 != s2){
std::cout << "Not Equal" << std::endl;
} else {
std::cout << "Equal" << std::endl;
}
}
void NotEqualExample(void) {
P s1;
s1.a = 'a';
s1.b = 'b';
s1.c = 'c';
P s2;
s2.a = 'a';
s2.b = 'b';
s2.c = 'd';
if(s1 != s2){
std::cout << "Not Equal" << std::endl;
} else {
std::cout << "Equal" << std::endl;
}
}
int main () {
EqualExample();
NotEqualExample();
}

Related

Cuda Implementation of Partitioned Subgroup

is there a more efficient way to implement the "Partitioned Subgroup" functions of Vulkan/OpenGL, which do not have to loop over all elements in the subgroup? My current implementation just uses a loop from 0 to WARP_SIZE.
References:
(slide 37+38) https://developer.download.nvidia.com/video/gputechconf/gtc/2019/presentation/s9909-nvidia-vulkan-features-update.pdf
https://github.com/KhronosGroup/GLSL/blob/master/extensions/nv/GL_NV_shader_subgroup_partitioned.txt
Simple Implementation:
__device__ uint32_t subgroupPartitionNV(ivec2 p)
{
uint32_t result = 0;
for (int i = 0; i < 32; ++i)
{
int x = __shfl_sync(0xFFFFFFFF, p(0), i);
int y = __shfl_sync(0xFFFFFFFF, p(1), i);
uint32_t b = __ballot_sync(0xFFFFFFFF, p(0) == x && p(1) == y);
if (i == threadIdx.x & 31) result = b;
}
return result;
}
__device__ uint32_t subgroupPartitionedAddNV(float value, uint32_t ballot)
{
float result = 0;
for ( unsigned int i = 0; i < 32; ++i)
{
float other_value = __shfl_sync(0xFFFFFFFF, value, i);
if ((1U << i) & ballot) result += other_value;
}
return result;
}
Thanks to the hint of Abator I came up with a more efficient solution. It's a little ugly because labeled_partition is only implemented for int but works quite well.
template <int GROUP_SIZE = 32>
__device__ cooperative_groups::coalesced_group subgroupPartitionNV(ivec2 p)
{
using namespace cooperative_groups;
thread_block block = this_thread_block();
thread_block_tile<GROUP_SIZE> tile32 = tiled_partition<GROUP_SIZE>(block);
coalesced_group g1 = labeled_partition(tile32, p(0));
coalesced_group g2 = labeled_partition(tile32, p(1));
details::_coalesced_group_data_access acc;
return acc.construct_from_mask<coalesced_group>(acc.get_mask(g1) & acc.get_mask(g2));
}
template <typename T, int GROUP_SIZE = 32>
__device__ T subgroupPartitionedAddNV(T value, cooperative_groups::coalesced_group group)
{
int s = group.size();
int r = group.thread_rank();
for (int offset = GROUP_SIZE / 2; offset > 0; offset /= 2)
{
auto v = group.template shfl_down(value, offset);
if (r + offset < s) value += v;
}
return value;
}

How can I get a variable in C to be used in a MySQL Query

I have a temperature sensor hooked up to a Raspberry Pi, I am able to read and printf the temperature. What I am trying to do next is to get the values from the sensor and have them get logged into a MySQL database.
Everything works, except, I can not figure out how to format the MySQL insert Query to use the f variable and the h variable that is generated by the read_dht_data() function and pass it to the MIA_temp_insert(float f, float h).
#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>
#include <wiringPi.h>
#include <stdint.h>
#define MAX_TIMINGS 85
#define DHT_PIN 3 /* GPIO-22 */
int data[5] = { 0, 0, 0, 0, 0 };
float temp_f;
static char *host = "XXX.XXX.XXX.XXX";
static char *user = "XXX";
static char *password = "XXX";
static char *dbname = "XXX";
unsigned int port = 3306;
static char *unix_socket = NULL;
unsigned int flag = 0;
static MYSQL *conn; //Needed to be static so all of the functions can draw from it
void MIA_mysql_connection()
{
// Connecting to the Database
conn = mysql_init(NULL);
if (!(mysql_real_connect(conn, host, user, password, dbname, port, unix_socket, flag)))
{
fprintf(stderr, "\n Error: %s [%d] \n", mysql_error(conn),mysql_errno(conn));
exit (1);
}
//Connected
printf ("We Are Connected \n");
}
void MIA_mysql_close()
{
//Closing Connection
mysql_close(conn);
}
void MIA_temp_insert(float f, float h)
{
//Inserting into MySQL Table
if(mysql_query(conn, "INSERT INTO `temperature` (`id`, `Date`,`Time`, `Temperature`, `Humidity`) VALUES (NULL, CURRENT_DATE(), CURRENT_TIME(), '%f' , '%f')") !=0)
{
fprintf(stderr, "%s\n", mysql_error(conn));
exit (-1);
} else {
printf("Rows were insert \n");
}
}
void read_dht_data()
{
uint8_t laststate = HIGH;
uint8_t counter = 0;
uint8_t j = 0, i;
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
/* pull pin down for 18 milliseconds */
pinMode( DHT_PIN, OUTPUT );
digitalWrite( DHT_PIN, LOW );
delay( 18 );
/* prepare to read the pin */
pinMode( DHT_PIN, INPUT );
/* detect change and read data */
for ( i = 0; i < MAX_TIMINGS; i++ )
{
counter = 0;
while ( digitalRead( DHT_PIN ) == laststate )
{
counter++;
delayMicroseconds( 1 );
if ( counter == 255 )
{
break;
}
}
laststate = digitalRead( DHT_PIN );
if ( counter == 255 )
break;
/* ignore first 3 transitions */
if ( (i >= 4) && (i % 2 == 0) )
{
/* shove each bit into the storage bytes */
data[j / 8] <<= 1;
if ( counter > 16 )
data[j / 8] |= 1;
j++;
}
}
/*
* check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
* print it out if data is good
*/
if ( (j >= 40) &&
(data[4] == ( (data[0] + data[1] + data[2] + data[3]) & 0xFF) ) )
{
float h = (float)((data[0] << 8) + data[1]) / 10;
if ( h > 100 )
{
h = data[0]; // for DHT11
}
float c = (float)(((data[2] & 0x7F) << 8) + data[3]) / 10;
if ( c > 125 )
{
c = data[2]; // for DHT11
}
if ( data[2] & 0x80 )
{
c = -c;
}
float f = c * 1.8f + 32;
//printf( "Humidity = %.1f %% Temperature = %.1f *C (%.1f *F)\n", h, c, f );
printf ("Temp of the room is : %.1f \n",f);
//Insert Data into MIA Temperature Table
MIA_temp_insert(10.0,11.1);
}else {
//printf( "Data not good, skip\n" );
}
}
int main ()
{
printf( "Raspberry Pi DHT11/DHT22 temperature/humidity test\n" );
if ( wiringPiSetup() == -1 )
exit( 1 );
while ( 1 )
{
MIA_mysql_connection();
read_dht_data();
delay (1000);
MIA_mysql_close();
printf("End of program \n");
}
return(0);
}
You cannot use printf()-style format specifiers in mysql_query() directly as you have above. Instead, you can use sprintf() or snprintf() to write the format string -- with the formatted numbers instead of format specifiers -- into a buffer... then pass that as your query string.
So in MIA_temp_insert(), instead of the following:
if(mysql_query(conn, "INSERT INTO `temperature` (`id`, `Date`,`Time`, `Temperature`, `Humidity`) VALUES (NULL, CURRENT_DATE(), CURRENT_TIME(), '%f' , '%f')") !=0)
{
fprintf(stderr, "%s\n", mysql_error(conn));
exit (-1);
/* ...etc... */
...you could try this:
/* Your original query string, with the %f specifiers */
const char *formatstring = "INSERT INTO `temperature` (`id`, `Date`,`Time`, `Temperature`, `Humidity`) VALUES (NULL, CURRENT_DATE(), CURRENT_TIME(), '%f' , '%f')";
/* snprintf() the query into a buffer, to fill in the numbers */
char buf[256]; // should be large enough for the query with the numbers filled in
if (snprintf(buf, sizeof(buf), formatstring, f, h) >= sizeof(buf))
{
exit(-1); // if snprintf() returned sizeof(buf) or more, buf was too short
}
/* call mysql_query() with the formatted query from the buffer */
if (mysql_query(conn, buf) != 0)
{
fprintf(stderr, "%s\n", mysql_error(conn));
exit (-1);
/* ...etc... */

Pass stream to function

vector<bool> retroswap (vector<bool> v)
{
reverse(v.begin(), v.end()) ;
for (int i = 0 ; i < v.size() ; i++)
{
if (v[i] == 0)
{
v[i] = 1 ;
} else {
v[i] = 0 ;
}
}
v.insert(v.begin(), 1) ;
return v ;
}
// Overloading the + operator
vector<bool> operator+ (vector<bool> gds, vector<bool> rs)
{
for (int i = 0 ; i < rs.size() ; i++)
{
gds.push_back(rs[i]) ;
}
return gds ;
}
ostream& operator<< (ostream& out, vector<bool> v)
{
for (int i = 0 ; i < v.size() ; i++)
{
out << v[i] << endl ;
}
return out ;
}
vector<bool> generate_dragon_sequence (vector<bool> v, int n, ostream& out)
{
if (n==1)
{
return v ;
}
vector<bool> rs = retroswap(generate_dragon_sequence(v, n-1, out)) ;
out << generate_dragon_sequence(v, n-1, out) + rs ;
return generate_dragon_sequence(v, n-1, out) + rs ;
}
Above is my code that i am doing for my school project. I have a question regarding passing ostream objects to functions. I am constructing a recursive function which generates larger and larger vectors according to an algorithm. All I want to do is to output the final vector product using the stream object
Hence, in int main(), if I were to write generate_dragon_function(v, n, cout), it will output the final vector to the console.
I was wondering how I could do it? Thank you so much guys!

Mips Function Call and declarion

I have the two following C++ functions:
void arprt(int arr[], int size, int perln){
int i = 0;
while (i != size){
cout << arr[i] << ' ';
i++;
if (i % perln == 0)
cout << endl;
}
}
int expos(int arr[], int size, int dest[]){
int i = 0, j = 0;
while (i != size){
if (arr[i] > 0){
dest[j] = arr[i];
j++;
}
i++;
}
return j;
}
I want to translate them to assembly (MIPS).
How can I do that?
Also, how can I call them??

In C, how can one convert HTML strings to C strings?

Is there a common routine or library available?
e.g. ' has to become '.
This isn't particularly hard, assuming you only care about &#xx; style entities. The bare-bones, let-everyone-else-worry-about-the-memory-management, mechanical, what's-a-regex way:
int hex_to_value(char hex) {
if (hex >= '0' && hex <= '9') { return hex - '0'; }
if (hex >= 'A' && hex <= 'F') { return hex - 'A' + 10; }
if (hex >= 'a' && hex <= 'f') { return hex - 'f' + 10; }
return -1;
}
void unescape(char* dst, const char* src) {
// Write the translated version of the text at 'src', to 'dst'.
// All sequences of '&#xx;', where x is a hex digit, are replaced
// with the corresponding single byte.
enum { NONE, AND, AND_HASH, AND_HASH_EX, AND_HASH_EX_EX } mode;
char first_hex, second_hex, translated;
mode m = NONE;
while (*src) {
char c = *src++;
switch (m) {
case NONE:
if (c == '&') { m = AND; }
else { *dst++ = c; m = NONE; }
break;
case AND:
if (c == '#') { m = AND_HASH; }
else { *dst++ = '&'; *dst++ = c; m = NONE; }
break;
case AND_HASH:
translated = hex_to_value(c);
if (translated != -1) { first_hex = c; m = AND_HASH_EX; }
else { *dst++ = '&'; *dst++ = '#'; *dst++ = c; m = NONE; }
break;
case AND_HASH_EX:
translated = hex_to_value(c);
if (translated != -1) {
second_hex = c;
translated = hex_to_value(first_hex) << 4 | translated;
m = AND_HASH_EX_EX;
} else {
*dst++ = '&'; *dst++ = '#'; *dst++ = first_hex; *dst++ = c;
m = NONE;
}
break;
case AND_HASH_EX_EX:
if (c == ';') { *dst++ = translated; }
else {
*dst++ = '&'; *dst++ = '#';
*dst++ = first_hex; *dst++ = second_hex; *dst++ = c;
}
m = NONE;
break;
}
}
}
Tedious, and way more code than seems reasonable, but not hard :)
I'd try to parse the number out from the string and then convert it to a number using atoi and then cast it to a character.
This is something I wrote in ~20 seconds so it's completely contrived:
char html[] = "'";
char* pch = &html[2];
int n = 0;
char c = 0;
pch[2] = '\0';
n = atoi(pch);
c = n;
now c is '. Also I don't really know about html strings... so I might be missing something
There is "GNU recode" - command line program and a library.
http://recode.progiciels-bpi.ca/index.html
Among other things it can encode/decode HTML characters.