How can I customize a unordered_map so that it uses a custom hash function and a custom equality function? - hash

How can I write my own hash and equity operator for an unordered map so that I can use a char * instead of a std::string as a key?

class PtrStr
{
protected:
const char *m_pcStr;
const int m_nSize;
public:
PtrStr(const char *pcStr, int nSize) : m_pcStr(pcStr), m_nSize(nSize) {}
~PtrStr() {};
const char *GetStr() const { return m_pcStr; }
const int GetSize() const { return m_nSize; }
};
namespace std
{
namespace tr1
{
template<> struct hash<PtrStr>
{
std::size_t operator()(PtrStr const &key) const
{
return MyHashMethod(key);
}
};
}
template<> struct equal_to<PtrStr>
{
bool operator()(const PtrStr &keyA, const PtrStr &keyB) const
{
return (strcmp(const_cast<PtrStr &>(keyA).GetStr(), const_cast<PtrStr &>(keyB).GetStr()) == 0);
return (strcmp(keyA.GetStr(), keyB.GetStr()) == 0);
}
};
}
typedef std::tr1::unordered_map<PtrStr, int> unorderedCharMap;
typedef std::tr1::unordered_map<PtrStr, int>::iterator unorderedCharMapItr;

Related

flutter - Comparing two lists of objects isn't working

I've two lists of objects that i wanna compare, a and b:
final dia = DateTime(2017, 9, 7, 17, 30);
final ppp = Parcela("1", 225.5, dia, null, 1, false, false);
final ppp2 =Parcela("1", 225, dia.add(const Duration(days: 3)), null, 1, false, false);
final ppp3 =Parcela("1", 225, dia.add(const Duration(days: 3)), null, 1, false, false);
List<Parcela> a = [ppp,ppp2,];
List<Parcela> b = [ppp, ppp3];
Both of them are equal, but when i try to check it with the functions bellow i get false on response:
print(a.every(b.toSet().contains));
print(listEquals(a, b));
I tried also "quiver" and "collection" libraries from pub dev but the result is the same
The Parcela model:
class Parcela {
String id;
double valor;
DateTime dataPagamento;
DateTime dataPago;
int status;
int ref;
Parcela(String id, double valor, DateTime dataPagamento, DateTime dataPago,
int ref, bool pago, bool atraso) {
this.id = id;
this.valor = valor;
this.dataPagamento = dataPagamento;
this.dataPago = this.dataPago;
this.status = _getStatus(pago, atraso);
this.ref = this.ref;
}
int _getStatus(bool pago, bool atraso) {
if (pago) {
if (atraso) {
return 3;
} else {
return 1;
}
} else {
if (atraso) {
return 2;
} else {
return 0;
}
}
}
}
Edit1:
I've tried Dan James suggestion but my class isn't final as his, so i've removed "final" from name attribute:
class Person extends Equatable {
Person(this.name);
String name;
#override
List<Object> get props => [name];
}
the new test vars:
Person p = Person("name");
Person p2 = Person("name2");
Person p3 = Person("tobias");
List<Person> aa = [p, p2];
List<Person> bb = [p, p2..name = "teste"];
List<Person> cc = [p, p3];
but when i test the lists:
var filtered_lst =List.from(aa.where((value) => !bb.contains(value)));
print(filtered_lst);
print(listEquals(aa, bb));
print(listEquals(aa, cc));
the console returns this:
I/flutter (12746): []
I/flutter (12746): true
I/flutter (12746): false
ppp2 does not equal ppp3 because they are two different instances of a class. You could override the '==' operator to check if each field is the same. ie. ppp2.id == ppp3.id.
eg/ (taken from equatable docs but this is vanillar dart)
class Person {
const Person(this.name);
final String name;
#override
bool operator ==(Object other) =>
identical(this, other) ||
other is Person &&
runtimeType == other.runtimeType &&
name == other.name;
#override
int get hashCode => name.hashCode;
}
Or look into the equatable package which does this for you. https://pub.dev/packages/equatable
Straight from the equatable docs:
import 'package:equatable/equatable.dart';
class Person extends Equatable {
const Person(this.name);
final String name;
#override
List<Object> get props => [name];
}
Using the library equatable from Dan James answer:
import 'package:equatable/equatable.dart';
// ignore: must_be_immutable
class Parcela extends Equatable {
String id;
double valor;
DateTime dataPagamento;
DateTime dataPago;
int status;
int ref;
Parcela(String id, double valor, DateTime dataPagamento, DateTime dataPago,
int ref, bool pago, bool atraso) {
this.id = id;
this.valor = valor;
this.dataPagamento = dataPagamento;
this.dataPago = this.dataPago;
this.status = _getStatus(pago, atraso);
this.ref = this.ref;
}
int _getStatus(bool pago, bool atraso) {
if (pago) {
if (atraso) {
return 3;
} else {
return 2;
}
} else {
if (atraso) {
return 1;
} else {
return 0;
}
}
}
#override
List<Object> get props => [id,valor,dataPagamento,];
}
The only way of copying a list that doesn't point to the same memory address:
List<Parcela> copyParcelas(List<Parcela> list) {
List<Parcela> copyList = [];
for (var item in list) {
List<bool> _status = pagoAtraso(item.status);
Parcela betItems = Parcela(item.id, item.valor, item.dataPagamento,
item.dataPago, item.ref, _status[0], _status[1]);
copyList.add(betItems);
}
return copyList;
}
Then the check to return the list items that changed:
List<Parcela> editarParcelas(List<Parcela> parcelas, List<Parcela> original){
return filteredlst = parcelas.toSet().difference(original.toSet()).toList();
}

How can I handle raw bytes on dart?

I'm totally new at app developing.
I trying to communicate with C-written end device via raw UDP packet. (such a modbus-like protocol)
And I'm suffering pain with serial/deserializing class(struct).
Here is a simple class, Packet which contain uint32, uint16, uint8.
Pack() is working, but are there any better way to achieve that?
I don't know how can I implement Unpack() method. I mean, how can I convert Uint8List to int?
import 'dart:typed_data';
void main() {
var pkt = new Packet();
pkt.TID = 0x01234567;
pkt.Src = 0x89;
pkt.Des = 0xab;
pkt.Data = 0xcdef;
var buf = pkt.Pack();
print('Packed: ${buf}');
var pkt_2 = new Packet();
if (pkt_2.Unpack(buf) != null) {
print("panic!");
return;
}
print('UnPacked: ${pkt_2.toString()}');
}
class Packet {
int TID; // uint32
int Src; // uint8
int Des; // uint8
int Data; // uint16
static const SIZE = 8;
String toString() {
return 'TID: ${TID.toRadixString(16)}, Src:${Src.toRadixString(16)}, Des:${Des.toRadixString(16)}, Data:${Data.toRadixString(16)}';
}
Uint8List Pack() {
var buf = Byteconv.itou32(TID) +
Byteconv.itou8(Src) +
Byteconv.itou8(Des) +
Byteconv.itou16(Data);
return Uint8List.fromList(buf);
}
Error Unpack(Uint8List buf) {
if (buf.length != SIZE) {
return Error();
}
// What can I do?
// TID =
// Src =
// Des =
// Data =
return null;
}
}
class Byteconv {
static Uint8List itou64(int val) {
return Uint8List(8)..buffer.asByteData().setUint64(0, val, Endian.big);
}
static Uint8List itou32(int val) {
return Uint8List(4)..buffer.asByteData().setUint32(0, val, Endian.big);
}
static Uint8List itou16(int val) {
return Uint8List(2)..buffer.asByteData().setUint16(0, val, Endian.big);
}
static Uint8List itou8(int u8) {
return Uint8List(1)..buffer.asUint8List()[0] = u8;
}
}
SOLVED
var buf_view = ByteData.sublistView(buf);
TID = buf_view.getUint32(0);
Src = buf_view.getUint8(4);
Des = buf_view.getUint8(5);
Data = buf_view.getUint16(6);

add new elements to class

I've written a class like this,
class LessonCategory{final String name;
LessonCategory(this.name);
#override
String toString() {
return 'LessonCategory{name: $name}';
}
}
class Lessons {
final String lessonsName;
int discontinuity;
final LessonCategory lesscategory;
Lessons(this.lessonsName, this.discontinuity,
this.lesscategory,
);
#override
String toString() {
return 'Lessons{lessonsName: $lessonsName, discontinuity:
$discontinuity, lesscategory: $lesscategory}';
}
}
class Data {
static List<LessonCategory> categories = [
LessonCategory("a1"),
];
static List<Lessons> lessons = [
Lessons(
'Lesson A1',
0,
getCategoryFromName("a1"),
),
];
static LessonCategory getCategoryFromName(name) {
return categories.firstWhere(
(c) => c.name.toLowerCase() == name.toString().toLowerCase());
}
}
But I can't figure out how to add a new element.I already tried add,push,insert (or i missed something).
Can someone please show me the right way?
i want something like
Data.lessons.add({
lessonsName: 'Lesson Z1',
discontinuity: 0
lessCategory: 'a1'
});
just remove static syntax. if it is defined as static, it will be immutable
class Data {
static List<LessonCategory> categories = [
LessonCategory("a1"),
];
List<Lessons> lessons = [ // Remove Static syntax
Lessons(
'Lesson A1',
0,
getCategoryFromName("a1"),
),
];
static LessonCategory getCategoryFromName(name) {
return categories.firstWhere(
(c) => c.name.toLowerCase() == name.toString().toLowerCase());
}
}
but also we can correct another syntaxes
Data newData = Data();
newData.lessons.add(Lessons(
'Lesson Z1', // remove named parameters, and use positional params
0,
LessonCategory('a1'),
));
print("New Length : ${newData.lessons.length}");
Fully working code
class LessonCategory {
final String name;
LessonCategory(this.name);
#override
String toString() {
return 'LessonCategory{name: $name}';
}
}
class Lessons {
final String lessonsName;
int discontinuity;
final LessonCategory lesscategory;
Lessons(
this.lessonsName,
this.discontinuity,
this.lesscategory,
);
#override
String toString() {
return """Lessons{lessonsName: $lessonsName, discontinuity: $discontinuity, lesscategory: $lesscategory}""";
}
}
class Data {
static List<LessonCategory> categories = [
LessonCategory("a1"),
];
List<Lessons> lessons = [ // Remove Static syntax
Lessons(
'Lesson A1',
0,
getCategoryFromName("a1"),
),
];
static LessonCategory getCategoryFromName(name) {
return categories.firstWhere(
(c) => c.name.toLowerCase() == name.toString().toLowerCase());
}
#override
String toString() {
return "{${lessons.map((fruit) => print(fruit))}}";
}
}
main(List<String> args) {
Data newData = Data(); // Create instance first
newData.lessons.add(Lessons(
'Lesson Z1', // remove named parameters, and use positional params
0,
LessonCategory('a1'),
));
print("New Length : ${newData.lessons.length}");
newData.lessons.add(Lessons(
'Lesson Z1',
0,
LessonCategory('a1'),
));
print("New Length : ${newData.lessons.length}");
print("${newData.lessons}");
}
which we able to play arount in Dartpad
Result
remove the static syntax and the problem will be solved

C++ overloading operator, compiler doesn't see the operator

CMagazin.h
class CMagazin
{
char *m_nume;
list<CProdus*>List_produse;
public:
void printExpirabile( const char* data);
~CMagazin();
};
CMagazin.cpp
void CMagazin::printExpirabile(const char *xdata)
{
list<CProdus*>::iterator it;
for (it = List_produse.begin(); it != List_produse.end(); ++it)
{
CProdus* p = *it;
if (p->get_tip()=='A')
{
**if (p > xdata)**->this problem
}
}
}
CAliment.h
class CAliment :
public CProdus
{
char *m_expirare;
public:
bool operator >(const char*date);
~CAliment();
};
CAliment.cpp
bool CAliment::operator>(const char * date)
{
if (atoi(this->m_expirare) < atoi(date))
{
return 1;
}
else
{
return 0;
}
}
its about ">" operator.in CMagazin.cpp dont use my operator...i need help.
what can i do?I need ">" in CMagazin class. class CAliment its a class derived from CProdus.
Answer is: in Class CProdus the operator must be declared virtual, and in
CMagazin.cpp
void CMagazin::printExpirabile(const char *xdata)
{
list<CProdus*>::iterator it;
for (it = List_produse.begin(); it != List_produse.end(); ++it)
{
CProdus* p = *it;
if (p->get_tip()=='A')
{
if (p->operator>( xdata))-> make this!
{
p->print();
}
}
}
}
CProdus*p - is a pointer , need to have object for use this operator -> Try (*p)>xdata
void CMagazin::printExpirabile(const char *xdata)
{
list<CProdus*>::iterator it;
for (it = List_produse.begin(); it != List_produse.end(); ++it)
{
CProdus* p = *it;
if (p->get_tip()=='A')
{
if ((*p)>( xdata))-> make this!
{
p->print();
}
}
}
}

how to pass char pointer to function and return another string in ( C )?

i have a code to find table name in SQL query . i create function to check char pointer and i need return table name string .
my function
char* SQLParser_GetTable(char *query)
{
const char *str = "my string";
return *str;
}
void PrintRows(char *TableName)
{
}
void doSELECT(char *query)
{
printf("do SELECT :");
PrintRows(SQLParser_GetTable(*query));
}
const char* SQLParser_GetTable(char *query)
{
const char *str = "my string";
return str;
}