Clang-Format indent class members - clang

Is there a Clang-Format style option to indent class members independantly from access modifiers? In the picture below line 10 is how I'd like it, whereas line 11 is how it's currently formatting.
class AudioService : public IAudioService
{
public:
void Prepare(); // how I'd like it
void Destroy(); // How it currently is formatting
}

You can achieve this by using the AccessModifierOffset option, which is used to set the extra indent or outdent of access modifiers.
Here is an example .clang-format:
Language: Cpp
BreakBeforeBraces: Linux
IndentWidth: 8
AccessModifierOffset: -4
After calling clang-format with this configuration, you'll get the following formatting:
class AudioService : public IAudioService
{
public:
void Prepare(); // how I'd like it
void Destroy(); // How it currently is formatting
}

Related

Have single line empty constructors, but braces on newline everywhere else

I am looking for a way to make clang-format allow single line empty constructors, but to put braces on the newline everywhere else.
Ideally I want to support these three cases all with one clang config.
Test::Test(const std::string &name) : name(name) {}
std::string Test::get_name()
{
return name;
}
void Test::blank()
{
}
Is there a way to special case constructors in anyway? Even being able to have empty functions on a single line the same as constructors would be acceptable. But putting short functions on a single line is not acceptable.
This doesn't solve all the issues, but it solves my main case.
AllowShortFunctionsOnASingleLine: InlineOnly
This will allow short functions in class definitions to be single line.
From https://clang.llvm.org/docs/ClangFormatStyleOptions.html
SFS_InlineOnly (in configuration: InlineOnly) Only merge functions defined inside a class. Same as “inline”, except it does not implies “empty”: i.e. top level empty functions are not merged either.
class Foo {
void f() { foo(); }
};
void f() {
foo();
}
void f() {
}
This combined with BreakBeforeBraces: Allman gives me the desired result.

What is the correct way to define MQL4 "#import of static class methods"?

What I'm trying to achieve is define classes (using MQL4) in separate files and use the methods from those classes in the main code. Essentially importing static class member functions.
class example{ // ____ in example.mq4
public:
static void myfunction(void) export { .. do something .. }
}
class example{ // ____ in example.mqh
public:
static void myfunction(void);
}
#include <example.mqh> // ____ in main.mq4:
#import "example.ex4"
void example::myfunction(void);
#import
Results in a compile error when using the function as follows:
void OnInit(){
example::myfunction();
}
compiler error:
myfunction: function must have a body
(note example.mq4 is compiled to example.ex4 and can be imported ok)
"new"-MQL4 syntax is evolving
for the indicated purpose,
the class definition syntax shall be enough, upon instantiation of a class, its public methods are possible to be invoked on instance-objects.
Compile-time syntax:
Exporting a function without it's class-inheritance ( taking together the whole class container ) does not fit the OOP concept. This is clearly visible in the OnInit() call, where your code attempts to call a function, which is in fact a class-based object-method at a moment, where there has not yet been instantiated any object, on which the method ought to be performed anObjectINSTANCE.aClassOrInstanceMETHOD().
So, just #include
class example{ // ____ in example.mqh
public:
static void myfunction() { .. do something; }
}
// ---------------------------- // ____ in main.mq4
#property strict // "new"-MQL4
#include <example.mqh> // include
example anObject; // create a globally visible instance
// ----------------------------
void OnInit(){
anObject.myfunction(); // request <anObject> to perform <myfunction> method on self
return( EMPTY ); // "new"-MQL4 insists on return even on void fun()
}

What is the term for the '#' in Razor syntax?

The material I've read generally uses phrases like 'use the # character here to denote the start...' but I want to know what to call such a character. A coworker suggested the word 'token' but I don't think that's correct.
Brifely looking at the source code, the Razor team seem to refer to it as Transition Symbol.
In SyntaxConstants:
namespace System.Web.Razor.Parser
{
public static class SyntaxConstants
{
public static readonly char TransitionCharacter = '#';
public static readonly string TransitionString = "#";
}
}
Also in HtmlSymbolType.Transition:
namespace System.Web.Razor.Tokenizer.Symbols
{
public enum HtmlSymbolType
{
...
Transition, // #
}
}
Still, I doubt you can formally name it "Transition", it's seems more like an internal term of the parser to denote contexts switches (for example from HTML to C# and vice versa).

How to reference static classes in Actionscript

I apologize in advance for the newbiness of this question; I think I'm not grasping the basics of Actionscript but haven't been able to find an answer elsewhere.
What I want is some global constants like one would have in C++. In C++, I would simply have a file where I would #define MAP_HEIGHT 20, or something like that, and they would be globally accessible when I included the file at the top. In Actionscript, I've tried making a static class instead, like so:
package
{
public class Settings {
public const mapx:int = 20;
public function Settings() {}
}
}
But when I try to reference it in my code with colon syntax
var a:int = Settings::mapx;
I get the error "[Fault] exception, information=TypeError: Error #1034: Type Coercion failed: cannot convert Settings$ to Namespace."
I tried dot syntax:
var a:int = Settings.mapx;
and got a different error, "Access of possibly undefined property mapx through a reference with static type Class."
But what I really want is a file of global static variables, like in C++, and can't find a way to do it in Actionscript.
Mark variables, constants, and functions with the static keyword, as in:
package
{
public class MathUtil
{
public static const PI:Number = 3.141592653589;
public static function deg2rad(angle:Number):Number
{
angle = !isNaN(angle) ? (angle) : (0);
return angle * PI / 180;
}
}
}
Then you may use dot notation.
var pi:Number = MathUtil.PI;
var angle:Number = MathUtil.deg2rad(45);
From ActionScript 3.0 Reference for the Adobe Flash Platform: Statements, Keywords & Directives
Usage
class someClassName {
static var varName;
static const kName;
static function methodName() { }
}
You can use static in class definitions only, not in interface
definitions.
Static class members are not inherited. You cannot refer to a static
class member using the name of a subclass, as you can in Java or C++.
You can, however, refer to a static variable or method within a class
or subclass, without using any qualifier. See the example below.
You cannot use the super statement or the this keyword inside a static
method.

Do C++ Templates play nicely with VCL classes?

I'm trying to use C++ Template 'mixins' to create some new VCL components with shared additional functionality. Example...
template <class T> class Mixin : public T
{
private:
typedef T inherited;
// ...additional methods
public:
Mixin(TComponent *owner) : inherited(owner)
{
// .. do stuff here
};
};
Used like this:
class MyLabel : public Mixin<TLabel>
{
....
}
class MyEdit : public Mixin<TEdit>
{
....
}
Now, everything compiles fine, and the mixin stuff seems to work - until I try and save the component to a stream using TStream->WriteComponent, where the inherited properties (eg TLabel.Width/Height/etc.) don't get written. This is even with a 'null' mixin like the one shown above.
My code works fine when just deriving classes directly from TForm, TEdit, etc - and the class is correctly registered with the streaming system.
The quick/simple answer is: no; when dealing with a template, the compiler won't generate the proper descriptors to make streaming working. However, since this has come up before, I peeked under the cover to find out what's missing. And what I found is that it's almost there. So here's a little more information.
Upfront the compiler will never treat a template-based type as a Delphi. For example, do something like this:
void testing()
{
__classid(Mixin<Stdctrls::TLabel>); // Error Here
}
... and you'll see the error
"Error E2242 test.cpp 53: __classid requires Delphi style class type (i.e. class marked __declspec(delphiclass) or derived from System::TObject) in function testing()"
This basically says the compiler does not consider this type/class as compatible with Delphi-classes [i.e. those that derive from TObject]. Internally there's just a flag on the symbol that says whether the type is delphi-compatible or not. And I noticed that I could trick the compiler into marking the type as delphi-style if I forced it to walk up the hierarchy.. which is something it has to do if I create an instance of the object. So, with this hack the error goes away:
void testing()
{
typedef Mixin<Stdctrls::TLabel> __ttype;
std::auto_ptr<__ttype> c2(new __ttype(0));
__classid(Mixin<Stdctrls::TLabel>); // No more errors here
}
But much nicer was actually to use the __declspec(delphiclass) directly on the template, as in:
template <class T>
class __declspec(delphiclass) Mixin : public T {
private:
int i;
typedef T inherited;
public:
__fastcall Mixin(TComponent *owner) : inherited(owner) {};
};
So now that the compiler treats the type as a delphi-style class without hacks, I peeked a little more and found the issue you're probably running into: Delphi classes have the TTypeData.PropCount field - http://docwiki.embarcadero.com/VCL/en/TypInfo.TTypeData - which is a sum of the class' properties, including those of its base classes. Due to the way the various pieces of information are computed, the compiler writes out a '0' for that field when a template is involved:(
You can see this by printing out the PropCount, as in:
#include <Stdctrls.hpp>
#include <cstdio>
#include <memory>
#include <utilcls.h>
class TCppComp : public Classes::TComponent {
int i;
public:
__fastcall TCppComp(TComponent* owner): Classes::TComponent(owner) {};
__published:
__property int AAAA = {read=i, write=i};
};
template <class T>
class __declspec(delphiclass) Mixin : public T {
private:
int i;
typedef T inherited;
public:
__fastcall Mixin(TComponent *owner) : inherited(owner) {};
};
typedef Mixin<TCppComp> TMixinComp;
void showProps(TClass meta) {
PTypeInfo pInfo = PTypeInfo(meta->ClassInfo());
int Count = GetPropList(pInfo, tkAny, NULL);
TAPtr<PPropInfo> List(new PPropInfo[Count]);
std::printf("Class: %s - Total Props:%d\n",
AnsiString(pInfo->Name).c_str(), Count);
GetPropList(pInfo, tkAny, *(reinterpret_cast<PPropList*>(&List)));
for (int i = 0; i < Count; i++) {
AnsiString propName(List[i]->Name);
std::printf("\t%s\n", propName.c_str());
}
}
void test() {
showProps(__classid(TCppComp));
showProps(__classid(TMixinComp));
}
int main() {
test();
return 0;
}
When run the above prints:
Class: TCppComp - Total Props:3
AAAA
Name
Tag
Class: #%Mixin$8TCppComp% - Total Props:0
IOW, Mixin shows up with '0' published properties while its base type has 3:(
I suspect the streaming system relies on this count and that's why inherited properties are not being written out in your setup.
I considered tweaking the generated descriptors at runtime but since we write them to _TEXT it's bound to trigger DEP.
I'll look at the logic that computes the PropCount to see if there's some way to get it to compute the correct number. If time allows, please do open a QC for this: now that I've peek underneath, I believe it would not require much effort to get this working as expected.
Cheers,
Bruneau
PS: In my sample I even had the Mixin publish a property and the compiler generated the correct descriptor for that property; however, the total count was still zero.

Resources