|
Disclaimer: The following is intended to run in embedded environments that may not have a compliant STL if they have the STL at all. Some of this code could be replaced on systems with The STL to use std:: functionality.
Anyway, it's code I wrote, but it's not my code that really impresses me about this, but rather the C++ compiler.
static_assert(pixel_type::template equals<gfx::rgb_pixel<16>>::value,
"this code needs to be ported for your display format");
That's a compile time check to determine if a pixel format is exactly the same as the specified pixel format.
Not impressed yet?
Those pixel formats are arbitrarily defined:
template<size_t BitDepth>
using rgb_pixel = pixel<
channel_traits<channel_name::R,(BitDepth/3)>,
channel_traits<channel_name::G,((BitDepth/3)+(BitDepth%3))>,
channel_traits<channel_name::B,(BitDepth/3)>
>;
template<size_t BitDepth>
using rgba_pixel = pixel<
channel_traits<channel_name::R,(BitDepth/4)>,
channel_traits<channel_name::G,((BitDepth/4)+(BitDepth%4))>,
channel_traits<channel_name::B,(BitDepth/4)>,
channel_traits<channel_name::A,(BitDepth/4),0,(1<<(BitDepth/4))-1,(1<<(BitDepth/4))-1>
>;
template<size_t BitDepth>
using gsc_pixel = pixel<
channel_traits<channel_name::L,BitDepth>
>;
template<size_t BitDepth>
using yuv_pixel = pixel<
channel_traits<channel_name::Y,((BitDepth/3)+(BitDepth%3))>,
channel_traits<channel_name::U,(BitDepth/3)>,
channel_traits<channel_name::V,(BitDepth/3)>
>;
And furthermore
template<
typename Name,
size_t BitDepth,
bits::uintx<bits::get_word_size(BitDepth)> Min=0,
#if HTCW_MAX_WORD >= 64
bits::uintx<bits::get_word_size(BitDepth)> Max= ((BitDepth==64)?0xFFFFFFFFFFFFFFFF:((1<<BitDepth)-1)),
#else
bits::uintx<bits::get_word_size(BitDepth)> Max= ((BitDepth==32)?0xFFFFFFFF:((1<<BitDepth)-1)),
#endif
bits::uintx<bits::get_word_size(BitDepth)> Default = Min,
bits::uintx<bits::get_word_size(BitDepth)> Scale = Max
>
struct channel_traits {
using type = channel_traits<Name,BitDepth,Min,Max,Scale>;
using name_type = Name;
using int_type = bits::uintx<bits::get_word_size(BitDepth)>;
using real_type = bits::realx<16<=BitDepth?HTCW_MAX_WORD:32>;
constexpr static const size_t bit_depth = BitDepth;
constexpr static const int_type min = Min;
constexpr static const int_type max = Max;
constexpr static const int_type default_ = Default;
constexpr static const int_type scale = Scale;
constexpr static const real_type scaler = 1/(real_type)Scale;
constexpr static const int_type int_mask = ~int_type(0);
constexpr static const int_type mask = bits::mask<BitDepth>::right;
static_assert(BitDepth>0,"Bit depth must be greater than 0");
static_assert(BitDepth<=64,"Bit depth must be less than or equal to 64");
static_assert(Min<=Max,"Min must be less than or equal to Max");
static_assert(Default>=Min,"Default must be greater than or equal to the minimum value");
static_assert(Default<=Max,"Default must be less than or equal to the maximum value");
#if HTCW_MAX_WORD >= 64
static_assert(Max<=((BitDepth==64)?0xFFFFFFFFFFFFFFFF:((1<<BitDepth)-1)),"Max is greater than the maximum allowable value");
#else
static_assert(Max<=((BitDepth==32)?0xFFFFFFFF:((1<<BitDepth)-1)),"Max is greater than the maximum allowable value");
#endif
static_assert(Scale>0,"Scale must not be zero");
};
I don't know of any other language that allows this kind of compile time expressiveness. I wish they did. Sometimes it feels like I'm "in dialogue" with the compiler rather than with the generated/runtime code as with most languages.
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
I have one more question.
I will try my best to describe the issue and hoping the discussion does not get centered on terminology and RTFM as in the past.
That is not an instruction on how to reply, just a polite request to get real and skip opinions.
( And if you think me saying this is rude...
I am just trying to get of the dime and writing it as politely as I know)
I did have resolved the syntax of "passing the class" , however now I am stuck with WHERE the class should be declared.
In layman terms - the calling object passes a class pointer to the function, which happens to be my own created library. I expect the library function to PROCESS the passed class...
And that is where I am not sure if I have to define / declare the SAME class again - this time in the library.
I did test this using / passing SINGLE variable pointer and it worked OK.
I am not sure what to do when the entire class is passed.
I do not think dupicating the class definition is vise.
(Maybe it needs to be declared as global to the project ?)
Any theoretical help , answer, would be appreciated, I can manage the code...
Cheers
class BT_UTILITY_LIBRARY_EXPORT BT_Utility_Library
{
public:
class Test;
QString DEBUG_Process(void);
QString DEBUG_Process(int *);
QString DEBUG_Process(class Test *);
QString DEBUG_Process_Class(class Test *);
QString REG_EXP_Process(void);
class Test
{
public:
int a;
QString text;
}TestPointer;
|
|
|
|
|
It sounds like you're trying to implement in interface. Typically you'd do this by determining what behaviors an object might require and write a base (abstract) class that captures that. You then write your library functions so that they only make use of the public functions in the base class. The derived objects implement the methods in the base class in a way that makes sense for the derived object. There's plenty of examples out there, just google for "C++ interface" or "C++ abstract class". Almost any of which will give you better examples that I can come up with.
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
Could somebody please help me with solving this?
note: passing argument
to parameter 'Agrument' here
QString DEBUG_Process_Class(class REG_EXP_Class *Agrument );
I just cannot find any RTFM to "passing class pointer" to function ,
and I have no issues passing int * to a function.
Thanks for the reply.
I am not sure HOW to change to the "abstract class".
I have been struggling with Qt implementation of anything related to inheritance.
Anyway,
I did implemented the "supporting " class as a global variable.
I have not done "globals" for years and it was an OF memory exercise...
pREG_EXP_Class = new REG_EXP_Class;
pREG_EXP_Class->a = 10;
pREG_EXP_Class->text = "test text ";
pBTUL->DEBUG_Process_Class(pREG_EXP_Class);
All is working , until I did try to actually pass the class pointer...
Then I get this error and have no ideas where is my coding error.
/mnt/A_BT_DEC10/A_MAY_9_MAY31_CLEAN_BACKUP/A_APR9_MAR7_MAR19_CLEAN/A_BT_LIBRARY/A_DEC17_Bluetoothctl_Dialog_V1/mainwindow_bluewtoothctl_dialog.cpp:8911:
error: cannot initialize a parameter of type 'class REG_EXP_Class *' with an lvalue of type 'REG_EXP_Class *'
mainwindow_bluewtoothctl_dialog.cpp:8911:28: error: cannot initialize a parameter of type 'class REG_EXP_Class *' with an lvalue of type 'REG_EXP_Class *'
pBTUL->DEBUG_Process_Class(pREG_EXP_Class);
^~~~~~~~~~~~~~
../A_DEC17_BT_Utility_Library/bt_utility_library.h:59:54: note: passing argument
to parameter 'Agrument' here
QString DEBUG_Process_Class(class REG_EXP_Class *Agrument );
^
I could use some advise how to correctly pass the class pointer, this
"try this ... try that" is tedious.
and before I get " get a book..." I have no idea under what subject to look for...
" passing paramater to argument " ???
modified 3-Jun-24 10:29am.
|
|
|
|
|
QString DEBUG_Process_Class(class REG_EXP_Class *Agrument );
Remove the word class from the parameter in your function definition. The type REG_EXP_Class* is complete, it tells the compiler that Agrument is a pointer to an object of the REG_EXP_Class class. I would also suggest you remove the word Class from your class names, as it is redundant.
|
|
|
|
|
I explained what you should do to correct this in my previous reply. Passing a class pointer or reference is just the same as passing any other type. So a simple example:
class Foo
{
private :
int bar;
public:
Foo(int i) : bar(i) {} int getBar() {return bar; } };
int MyFunc(Foo* param)
{
int rc = param->getBar(); return rc * 2; }
int main
{
Foo* pFoo = new Foo(4); int ans = MyFunc(pFoo); cout << "result: " << ans << endl;
return 0;
}
And all of that, and more, is fully explained in any C++ reference, either online or in printed copy.
|
|
|
|
|
I am trying to improve my C++ skills and could use some advice.
I am using event driven tool - I am not allowed to say the name here -
and my basic question is
if I create an instance of a class which uses a library
should the library by instantiated in class constructor
as a common to all class methods variable
or
be instantiated in each method ( as a local method variable ) as needed ?
Process speed is immaterial, my question is about how is
memory allocated / de-allocated ( managed by C++) during the events.
|
|
|
|
|
You do not normally instantiate a library. If the library contains classes then you would instantiate objects as you need them. If it only contains functions then there is nothing to instantiate. But without details of the actual library and how you want to use it, it is not possible to be clearer.
|
|
|
|
|
This is probably best answered by the provider of the library. Is the library smart enough to know it's been initialized, so repeated initializations don't leak resources? Does the library need to initialized per thread, per object created, or on some other scheme? Is finalization needed? If so, is that per thread/object/other?
As Richard points out, without more detail, we'd just be guessing.
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
Maybe the answer is in this approach
create an instance of the object
create primary method and create local instance of the library
create secondary method and again create local instance of the library
that way there are two instances of the library "in use "
the compiler /linker may flag it or not
I really think the issue is - these methods are events and "go away" when done - which is really
confusing as far as actual C++ "deleting" unused stuff.
|
|
|
|
|
Salvatore Terress wrote: create primary method and create local instance of the library
create secondary method and again create local instance of the library As I said above, there is no "ceate an instance of a library". A library is linked into your application and appears (at the excution level) as if it is just part of your code. So please read my answer once again, or get yourself a good book on C++.
|
|
|
|
|
When we talk about a library we generally mean a DLL (.so in linux world) or static library (.a in linux) that is linked in with your code. That being the case, there is only one instance of any given library during the execution of a single process1, even if its multi threaded. Either you don't understand this, or you're using the term library to refer to something else. If the latter, you need to explain your concerns differently.
The difference between a DLL and a static library, in case you don't know, is that the functions in a static library are linked in at compile time, while dynamic libraries are linked in at run time. That means that when a change is introduced in a library (bug fix, for example), a program that is linked against a static library needs to be relinked after the static library has been compiled and installed. A program that is linked against a DLL gets the benefit of the change the next time it is run, without the need to relink it.
1There is a way to get multiple copies of a shared library attached to a single process, but that involves using dlopen() and friends, which I assume you're not doing here.
Update: Just checked, multiple calls to dlopen() does not attach multiple instances of a library to a process, so ignore that bit.
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
modified 30-May-24 15:56pm.
|
|
|
|
|
Thank you for your constructive contribution to this discussion. Appreciate your input and now I have a better understanding of the process.
|
|
|
|
|
This post original subject - error: declaration of anonymous class must be a definition
was caused by this class declaration
< class REG_EXP
{
int a;
QString text;
QString RegExp;
QString Analyze;
} TEST_REG_EXP;
/pre>
Search for the symbol "REG_EXP" in the entire project returned no result.
The conclusion
it is unknown why the error was posted.
Please consider this matter closed.
modified 30-May-24 19:43pm.
|
|
|
|
|
What the compiler is trying to tell you is that you have an invalid function definition, namely
void PassTrace(class *Pointer);
Think about that a little bit. What is the type of Pointer ? If your definition of PassTrace (i.e. the place where you provide the code for the function) matches the given declaration, how would you access any of Pointer 's members? Does the class have member a , or a member name , value ? There's no way to know.
Perhaps you meant
void PassTrace(Test *Pointer) or maybe you want a Template?
template <typename T>
void PassTrace<T *Pointer>
{
}
If you know that you'll never need to test *Pointer for null, you might consider using a reference rather than a pointer, and if you're not going to change the contents of what Pointer points to, then consider marking it as const as well.
Other than that, passing a pointer to a class (or struct) is no different that passing a pointer to anything else:
class myClass {
};
void f(myClass *pointer)
{
}
int main()
{
myClass c;
f(&c); }
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
Thank you, appreciate your reply.
I did JUST modify my working test function and do not see why my definition is wrong.
I am obviously missing something VERY basic here.
Should it work this way ?
void BT_Utility_Library::PassTrace(class *)
// {
// //qDebug()<<pointer.
};
<pre="" lang="C++">
// void BT_Utility_Library::PassTrace(class *Pointer)
// {
// //qDebug()<<Pointer.
// };
void BT_Utility_Library::AddFive(int* Number)
{
*Number = *Number + 5;
}
|
|
|
|
|
void BT_Utility_Library::PassTrace(class *)
You cannot have a pointer that has no definition. The class keyword is usaed to define an actual class, whether abstract or not. In the definition above the pointer must be of an actual class so the compiler knows what to do with any statements that use it.
modified 26-May-24 6:44am.
|
|
|
|
|
consider:
class A { }
class B { }
class C { }
void f(class *ptr);
Which class does ptr refer to in void f(class *ptr) ? The definition of void f(class *ptr) makes as much sense as void f(const i) . There's no type associated with the parameter, so the compiler does not know what type the parameter is.
Note: The use of class or struct for a variable/parameter declaration is optional in C++ :
class C { }
int main()
{
class C c1;
C c2;
} the declarations of c1 and c2 are both valid, and both declare a object of type class C
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
Sorry, what was the question?
|
|
|
|
|
error: declaration of anonymous class must be a definition
and do not known how and where to correct this error.
STAND BY
I have another fish to fry and I need to rebuild this task from scratch.
I took a wrong approach and that is why I got this error.
|
|
|
|
|
UPDATE
DONE
"Match any number of characters , (from start of the line) , until "new line \n " is reached :
QRegularExpression re( ".*\n");
TODO
match first word only (of each line )
match the entire text (first word of each line )
I am VERY sorry to be such bother, but I am actually looking
for someone / somebody willing to help me to interpret ( read) the Linux
regular expression manual to build the expression.
My task is to
match each and every FIRST word in multi-line string .
I am stuck at
"\w+"
which matches EVERY word in the entire text
I can post my current code when I get
"I am willing help you..."
response
Thank you very much for understanding .
Sal
modified 28-May-24 12:39pm.
|
|
|
|
|
|
Salvatore Terress wrote: using non C++ tool
I am guessing that you meant you found another solution so you did not need to use C++.
Because you can certainly build an interpreter and/or a regex engine using C++.
|
|
|
|
|
Thanks for reply. I have riposted this, hoping for help with constructing with C++ reg expression .
|
|
|
|
|
I'm trying to straighten out some pointer "arithmetic" in some existing code. The expressions themselves are overly ambiguous to say the least. In part of my readings, I've come across the "auto" keyword where the compiler deduces what type I need. At least that's what I got from all of the verbiage.
This seems a) dangerous and b) adds another level of mental indirection to what you are trying to accomplish. To me, software needs to be very clear and explicit in what data you are working with and what you intend to do with it. A lot of the "here is how auto will help you" descriptions justify it by saving typing when trying to make use of other classes, templates and the like. It feels like the C++ committee came up with a feature A then added feature B to make using A easier. I'm now doing battle with lambda expressions - another story.
So, in your code - do you make extensive use of auto, and how does it help you?
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|