Re: win64 as orphan?
On 6/9/2014 11:42 AM, lurker wrote: i agree with you, but you should have posted in "announce", so that adrei can use it for some marketing. i too wait now for a long, long time to use it with win64. i am also giving up - i guess it will stay a linux/apple show. maybe, as a multiple os compiler, you can use lazarus or code typhon. cheers. On Monday, 9 June 2014 at 15:04:19 UTC, trail wrote: will the sorry state of the win64 headers and programs like dfl be fixed or is it time to leave the language to linux and move on to something else? Clang can parse windows.h these days, it might be worthwhile to use their toolchain to dump the various SDKs of windows.h into some kind of database with it, and write an exporter for the database to D. I imagine there is some overlap here that other languages could use something like this to provide up to date windows bindings (MingW in particular, and anyone else making new languages) I'm sure some hand additions would need to exist but a huge amount of the API could probably be handled with something like that.
Re: what keeps a COM object alive?
On 6/11/2013 10:38 PM, finalpatch wrote: A typical COM server would create a new object (derived from IUnknown), return it to the caller (potentially written in other languages). Because the object pointer now resides outside of D's managed heap, does that mean the object will be destroyed when the GC runs? A normal COM object written in C++ relies on reference counting to manage its life cycle but in D the ref counting seems not serving any purpose. The AddRef()/Release() of std.c.windows.com.ComObject maintains a ref count, but doesn't really use it for any thing. There's a comment in Release() says "let the GC reap it", but how does the GC know the object is okay to destroy? COM is by definition ref counted. In D you generally need to store a COM pointer in a struct and maintain the refcount with that struct (increment on copy, decrement in destructor, etc). Its not too hard, as 'alias this' usage can wrap the pointer's methods easily enough.
Re: WindowProc in a class - function and pointer problem
On 5/22/2013 8:49 PM, evilrat wrote: On Wednesday, 22 May 2013 at 21:42:32 UTC, D-sturbed wrote: Yes I'm in the "multiple Window case", every window is wraped in a class and has its own message handler. I know that Win, in its callback system, often lets you retrieve a pointer to something, and I haven't get it was possible in this case...(which is you seem to describe). I will try this tomorrow. you can't really make it without static wndproc. if you don't know how to do it just go google some wndproc in a class tutors for c++, i can even recommend you one(i had used my own port of this in D before i switched to crossplatform lib for my needs) - http://blogs.msdn.com/b/oldnewthing/archive/2005/04/22/410773.aspx I had a partial port of WTL over to D which worked well enough for what I needed, the core of the WndProc handling is down below. Each HWND is owned by the thread it was created on, so assigning it into D associative array (which is thread local) can do the trick. It involved a hack, before any call to the Win32 CreateWindow/CreateWindowEx APIs, to capture the association with the new HWND and to remove them when they get cleaned up. There is probably a better way but this worked enough to get started, and should work with multiple windows reasonably well. CWindowInterface g_CreatingWindow; CWindowInterface[HWND] g_HWNDtoObject; extern (Windows) int CWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { int WindowProcReturnValue = 0; /* auto EventMsg = appender!string(); formattedWrite(EventMsg, "EventMsg (hWnd=%1$s) (uMsg=%2$s) (wParam=%3$s) (lParam=%4$s)\n", cast(DWORD)hWnd, cast(DWORD)uMsg, cast(DWORD)wParam, cast(DWORD)lParam); OutputDebugString(toUTFz!(const(wchar)*)(EventMsg.data)); */ if (g_CreatingWindow) { g_HWNDtoObject[hWnd] = g_CreatingWindow; g_CreatingWindow = null; } auto Window = g_HWNDtoObject[cast(HANDLE)hWnd]; if (Window is null) { WindowProcReturnValue = DefWindowProc(hWnd, uMsg, wParam, lParam); } else { WindowProcReturnValue = Window.WindowProc(hWnd, uMsg, wParam, lParam); } if (uMsg == WM_NCDESTROY) { g_HWNDtoObject.remove(hWnd); } return WindowProcReturnValue; }
Re: Interface vs pure abstract class - speed.
On 5/12/2013 12:31 PM, SundayMorningRunner wrote: Hello, let's say I have the choice between using an abstract class or an interface to declare a "plan", a "template" for the descendants. From the dmd compiler point of view, should I use the abstract class version (so I guess that for each method call, there will be a few MOV, in order to extract the relative address from the vmt before a CALL) or the interface version (are the CALL directly performed in this case). Are interface faster ? (to get the address used by the CALL). Thx. If you actually need speed you would need to use something known as the curiously recurring template, and avoid using virtual (as much as possible) altogether.
Re: Recipe and best practice for accessing COM
On 9/9/2012 7:57 AM, Sean Cavanaugh wrote: On 9/9/2012 7:30 AM, newToCOM wrote: I've been super busy at work so haven't had much time to respond to this thread. I also have a D version of something resembling ATL's CComPtr which I am finally happy enough with to share, that I could post when i get home later tonight. The class is a good argument for keeping the rather esoteric opDot operator, since alias this is extremely dangerous for smart pointer structs in D.
Re: Recipe and best practice for accessing COM
On 9/9/2012 7:30 AM, newToCOM wrote: Still struggling.. test.d: --- ( ... ) /* Other imports */ import win32.directx.d2d1; alias win32.directx.d2d1.IID IID; IID IID_ID2D1Factory = { 0x06152247, 0x6F50, 0x465A, [0x92, 0x45, 0x11, 0x8B, 0xFD, 0x3B, 0x60, 0x07] }; extern (Windows) int WinMain( ... ) { ( ... ) /* Boilerplate code */ } int myWinMain( ... ) { ( ... ) /* Register class, Create window, show window, message loop */ } LRESULT WndProc( ... ) { switch (message) { ( ... ) /* Default and case WM_DESTROY */ case WM_CREATE: // arg2 REFIID pIID_ID2D1Factory; pIID_ID2D1Factory = cast(REFIID)&IID_ID2D1Factory; // arg3 D2D1_FACTORY_OPTIONS factoryOptions; factoryOptions.debugLevel = D2D1_DEBUG_LEVEL.INFORMATION; const D2D1_FACTORY_OPTIONS* pfactoryOptions = &factoryOptions; // arg4 void* pID2D1Factory; HRESULT hr = D2D1CreateFactory( D2D1_FACTORY_TYPE.SINGLE_THREADED, pIID_ID2D1Factory, pfactoryOptions, pID2D1Factory ); writeln(hr); // Prints 0 writeln(pID2D1Factory);// Prints a non-null pointer // Trying to use the interface float dpiX, dpiY; pID2D1Factory.GetDesktopDpi(dpiX, dpiY); // !!! Error: undefined identifier 'GetDesktopDpi' // I thought I had a pointer to the interface and could call // its methods... return 0; -- * Coffimplib was used to convert the d2d1.lib from Microsoft DirectX SDK (June 2010). The converted d2d1.dll was placed in C:\dcode\dlls * With test.d in C:\dcode, the file was compiled and linked in C:\dcode with: dmd test.d %cd%\dlls\d2d1.lib -I%cd%\dlls\ -version=DXSDK_JUNE_2010 - Why is the method identifier undefined? - Are there any code examples showing the right use of the bindings? In this example the pID2D1Factory is a void*, so it will need a cast to the proper type with a cast(ID2D1Factory) soemtime after the create call; Since this particular API takes an out void* (since it is capable of creating multiple unrelated types), it would need to look something like this: HRESULT hr = D2D1CreateFactory( D2D1_FACTORY_TYPE.SINGLE_THREADED, pIID_ID2D1Factory, pfactoryOptions, pID2D1Factory); if (SUCCEEDED(hr)) { assert(pID2D1Factory !is null); ID2D1Factory factory = cast(ID2D1Factory)pID2D1Factory; factory.GetDesktopDpi(dpiX, dpiY); } I've been super busy at work so haven't had much time to respond to this thread. Technically the API's fourth argument could be rewritten to be an 'out IUnknown', but then you are stuck calling QueryInterface, and back to having the exact same problem with the QueryInterface method.
Re: vector Cross/Dot using core.simd?
On 8/11/2012 8:23 PM, F i L wrote: I'm trying to write a Cross and Dot function using core.simd.float4 and DMD Does anyone know anything about SIMD operations that may be able to help me translate these functions into a D equivalent? I would very much appreciate your help. Some reference: C++ simd intrinsic for dot product (requires SSE 4.1, very modern) _mm_dp_ps C++ simd instrinsic for horizontal add (requires SSE3, also reasonably modern) _mm_hadd_ps If you are on SSE2 (which is the base spec for x64) and also the minimum CPU target we use at work for commercial game development, you are stuck doing shuffles and adds for dot product, which effectively process these operations as scalar). Ideally one of the sides of the dot product is an array and you can vectorize the dot product itself (1 vector vs 4 others, or 4 v 4). This is common when setting up shapes like view frustum culling (point tested against 6-8 extruded planes in an array)
Re: Recipe and best practice for accessing COM
On 7/24/2012 2:01 PM, newToCOM wrote: I am trying to use COM to access Windows functionality and APIs. I have read the interface documentation and some documentation at MSDN. I have seen the included sample snippet for IHello and the slides "Modern COM programming in D", but it is still not clear exactly what to do and what the best practice is. So, my question is: I have downloaded Windows SDK and coffimplib. How do I proceed to access d2d1 and draw a rectangle? A stepwise description of the recommended procedure is highly appreciated! I made D bindings for d3d11, directwrite, d2d1, and a few other directx APis. They are located at: http://www.dsource.org/projects/bindings/wiki/DirectX The bindings haven't had extensive testing but the bits i've used seem to work correctly (mostly in d3d11) The WindowsApi project is also necessary: http://www.dsource.org/projects/bindings/wiki/WindowsApi
Re: Is this actually supposed to be legal?
On 7/17/2012 12:23 PM, Jonathan M Davis wrote: On Tuesday, July 17, 2012 14:48:32 David Nadlinger wrote: On Tuesday, 17 July 2012 at 05:24:26 UTC, Jonathan M Davis wrote: This code strikes me as being a bug: class MyBase(T) {} class MySubA : MyBase!MySubA {} class MySubB : MyBase!MySubB {} void main() {} This pattern is actually quite common in C++ code, and referred to as CRTP (curiously recurring template pattern). If you propose to kill it, Andrei is going to get mad at you. ;) Well, it certainly seems insane to me at first glance - particularly when you take compile time reflection into account, since the derived classes' definitions are now effectively recursive (so I suspect that the situation is worse in D, since C++ doesn't have conditional compliation like D does). But if it's supposed to be legal, I guess that it's suppose to be legal. I'd never seen the idiom before, and it seemed _really_ off to me, which is why I brought it up. But I'd have to study it in order to give an informed opinion on it. - Jonathan M Davis A 'proper' D port of this kind design would be to use mixins instead of the template. They both accomplish the same thing: The template (or mixins) are written to call functions in the user defined type. A simple example would be the C++ WTL library: A user defined control defines its own window style, but the template code is responsible for creating the window, and accesses the style and class flags from the user defined type. The advantage is the same in both: you avoid making the interface virtual, you still get to use some generic code.
Re: align(16) struct member throws an exception with movdqa
On 6/11/2012 7:15 AM, Trass3r wrote: I think it has been fixed for the next version of DMD already. Any idea why align isn't letting me use movdqa? Cause align doesn't work the way you think it does. In fact I still don't understand how it works at all. The language align keyword can only reduce the alignment from the platform default (typically 8). A serious flaw if you ask me . . . .
Re: pure functions/methods
On 4/20/2012 3:06 AM, Namespace wrote: The sense of pure functions isn't clear to me. What is the advantage of pure functions / methods? I inform the compiler with "const" that this method does not change the current object, and therefore he can optimize (at least in C++) this method. How and what optimized the compiler if i have "pure" or "const pure" functions / methods? Simplest explanation I can think of is: a const function of a class can't modify its own classes data a pure function can't modify any data, or call other functions that are not also pure (though there are exceptions)
Re: Confused about github rebasing
On 3/15/2012 3:56 PM, Alex Rønne Petersen wrote: On 15-03-2012 21:53, Gour wrote: On Thu, 15 Mar 2012 13:49:14 -0700 "H. S. Teoh" wrote: Another question. How to I repair my current history, which is all messed up now? By not using DVCS which allows you to rewrite history (hint: check Fossil). ;) It's perfectly useful in DVCS. Without it, you'd have a mess of a history when you send your changes upstream. That's not really acceptable. Why would you delete history? Thats pretty much the primary purpose of source control.
Re: 0 < negative loop condition bug or misunderstanding on my part
On 3/7/2012 12:57 PM, Jonathan M Davis wrote: On Wednesday, March 07, 2012 11:01:05 Timon Gehr wrote: On 03/07/2012 07:05 AM, ixid wrote: Ah, thank you, so it's wrapping. That seems like a bad idea, what is the I suspect that the reality of the matter is that if we disallowed implicit conversions between signed and unsigned, a number of bugs would completely go away, but others would creep in as a result, and the overal situation wouldn't necessarily be any better, but I don't know. My initial reaction would be to agree with you, but there are definitely cases where such an approach would get annoying and bug-prone (due to the casting involved). But regardless, I really don't think that you're going to convince Walter on this one, given what he's said in the past. - Jonathan M Davis After writing enough container libraries and whatnot in C++, I always end up going bed while thinking life would be so much easier if implicit signed/unsigned conversions were not allowed. Then I go to sleep, wake up, and realize how much more horrific the code would be in other places if this was actually true. The best compromise would probably have been to make size_t signed when migrating to 64 bit memory addressing, and leave the unsigned/signed problems specificaly with size_t values back in the past of 32 bit and older systems. On a related note I would love to see something in std.somewhere (conv?) to provide a complete set of narrowing and signed/unsigned conversion functions: The matrix is basically the following methods: 1) Reduce size (64->32->16->8 bits) but maintain signedness with three types: 2) Methods to flip signedness of the value (but mainting bitwidth) multiplied against three types of operations: a) truncating (i.e. mask off the lower bits) b) saturating (values outside of range are clamped to min or max of the narrower range) c) throwing (values outside of narrow range throw a range exception)
Re: Linking with d3d11.dll/lib
On 2/23/2012 5:03 PM, John Burton wrote: I'm trying to use the d3d11 bindings in http://www.dsource.org/projects/bindings/wiki/DirectX to call direct3d11 functions from my D program. I've managed to get the code to compiler but when it links I get this error - Error 42 Symbol Undefined _D3D11CreateDeviceAndSwapChain@48 I have copied the D3D11.lib from the D3D SDK into my project and then run "COFFIMPLIB d3d11.lib -f" to convert it and included the library in my project settings. Is there something else I need to do to make this link? Any help appreciated. I modified my test app to use D3D11CreateDeviceAndSwapChain instead of D3D11CreateDevice and it links and runs against either function. The only trouble I had was when I went out of my way to delete the import libraries (d3d11.lib) in order to see what the link error looks like. I am currently using dmd2 2.057 and building my project with Visual Studio + VisualD plugin (0.30).
Re: Linking with d3d11.dll/lib
On 2/23/2012 5:03 PM, John Burton wrote: I'm trying to use the d3d11 bindings in http://www.dsource.org/projects/bindings/wiki/DirectX to call direct3d11 functions from my D program. I've managed to get the code to compiler but when it links I get this error - Error 42 Symbol Undefined _D3D11CreateDeviceAndSwapChain@48 I have copied the D3D11.lib from the D3D SDK into my project and then run "COFFIMPLIB d3d11.lib -f" to convert it and included the library in my project settings. Is there something else I need to do to make this link? Any help appreciated. Its been quite a while since I've had time to work on my side project (which is what prompted the d3d11 module to get written). I can look into this later when I get home, as well as strip down my test app and publish it somewhere. The app is pretty simple - it creates a window, a d3d11 device, a vertex and pixel shader, a vertex and index buffer, and draws a triangle. It would be more but I had been working on a stripped down version of the an ATL/WTL like wrapper for D in the meantime, in order to handle HWND objects and generate message maps with mixins.
Re: private module stuff
On 5/8/2011 4:05 AM, Jonathan M Davis wrote: Sean Cavanaugh: So I was learning how to make a module of mine very strict with private parts, and was surprised I could only do this with global variables and functions. Enums, structs, and classes are fully visible outside the module regardless of being wrapped in a private{} or prefixed with private. Am I expecting too much here? You are expecting the right thing. If you are right, then it's a bug that eventually needs to be fixed. Take a look in Bugzilla, there are several already reported import/module-related bugs. They're private _access_ but still visible. I believe that that is the correct behavior and not a bug at all. I believe that it's necessary for stuff like where various functions in std.algorithm return auto and return a private struct which you cannot construct yourself. Code which uses that struct needs to know about it so that it can use it properly, but since it's private, it can't declare it directly. It works because the types are appropriately generic (ranges in this case). Regardless, I believe that the current behavior with private is intended. - Jonathan M Davis The more I play with private/protected/package the more confused I am by it. For the most part the rules are: Functions and variables have protection Types (enum, struct, class) do not this and ~this are special and are not considered functions, and are always public struct and class members always default to public If you search phobos you will find occurences of 'private struct' and 'private class', so even the people writing libraries are expecting something to be happening that isn't. For example: //in std.parallelism: private struct AbstractTask { mixin BaseMixin!(TaskStatus.notStarted); void job() { runTask(&this); } } //and in std.demangle: private class MangleException : Exception { this() { super("MangleException"); } } and in my code I can compile the following without compile-time errors: import std.parallelism; import std.demangle; int main() { MangleException bar = new MangleException(); AbstractTask foo; foo.job(); return 0; } With the language the way it is now, it is nonsensical to have the attributes public/protected/package/private/export precede the keyword struct, class, or enum.
private module stuff
So I was learning how to make a module of mine very strict with private parts, and was surprised I could only do this with global variables and functions. Enums, structs, and classes are fully visible outside the module regardless of being wrapped in a private{} or prefixed with private. Am I expecting too much here? rough code: module mymoduletree.mymodule; private { struct foo { int x; int y; } int somevar = 4; } . module someothertree.othermodule; import mymoduletree.mymodule; int bar(int arg) { foo var; // why can i use this type here?? var.x = arg; var.y = somevar; // this generates an error (access of somevar is private and not allowed) return var.y; }
Re: Difference between stack-allocated class and struct
Here is my prototype COM compile-time reflection based wrapper mixin (which I have abandoned in favor of alias this since it covers 95% of my use cases even though it isn't perfectly safe). I am new at D so you have been warned, though this part of the language seems pretty straightforward enough. It is possible the track down the argument names but takes some rather intricate parsing to do correctly (and the example someone linked me in another thread of mine chocked on const types due to parsing bugs). http://snipt.org/xsu The wrapped interface also needs to be a mixin so it can be created in the correct module, with visibility to all the types passed to the interface's methods. So something like the following is going to fail miserably unless ComPtr is also made into a mixin and instantiated in the correct module. struct ComPtr(T) { public: T m_Pointer; mixin(WrapComInterface!(T)("m_Pointer") };
Re: Is int faster than byte/short?
On 4/30/2011 10:34 AM, Mariusz Gliwiński wrote: Hello, I'm trying to learn high-performance real-time programming. One of my wonderings are: Should i use int/uint for all standard arithmetic operations or int/short/byte (depends on actual case)? I believe this question has following subquestions: * Arithmetic computations performance * Memory access time My actual compiler is DMD, but I'm interested in GDC as well. Lastly, one more question would be: Could someone recommend any books/resources for this kind of informations and tips that could be applied to D? I'd like to defer my own experiments with generated assembly and profiling, but i suppose people already published general rules that i could apply for my programming. Thanks, Mariusz Gliwiński My experience with this pattern of thinking is to use the largest data type that makes sense, unless you have a profiler saying you need to do something different. However, if you get being obsessive-compulsive about having 'the perfectly sized integer types' for the code, it is possible to fall into the trap of over-using unsigned types 'because the value can never be negative'. Unsigned 8 and 16 bit values usually have a good reason to be unsigned, but when you start getting to 32 and 64 bit values it makes a lot less sense most of the time. When working with non-X86 platforms other problems are usually much more severe: More expensive thread synchronization primitives, lack of efficient variable bit bit-shifting (run-time determined number of bits shifted), non-existent branch prediction, or various floating point code promoting to emulated double precision code silently on hardware that can only do single precision floating point etc.
Quirks of 'alias foo this'
So my research into making a nice friendly to use COM interface wrapper for D has had a few odd turns and I am wondering if there is an answer to making the implementation nicer. I discovered the 'alias foo this' syntax to let structs nearly seamlessly impersonate a member variable. This has turned out to solve most of my original need to wrap the functions, but it is imperfect. The main problem with 'alias foo this' is that I am having is that I can't find a way to catch code reading the aliased variable, in cases of assignment or implicit conversion to foo type. I can catch writes just fine with opAssign, but finding a way to overload the reads have me stumped. I did some experiments with wraping the methods with some mixin templates, but using 'alias foo this' is about 100% more useful, intuitive and 99.9% less code to write :) Examples (The fully ComPtr code is down further): // initializes to null by default ComPtr!(ID3D11Device) device; ComPtr!(ID3D11Device) otherdevice; // The 'device' argument to D3D11CreateDevice is implemented as // 'out ID3D11Device', and uses the 'alias p this' feature to // auto-magically write directly into device.p; Ideally // I could hook this and either call SafeRelease here or assert // that the p variable is null before being written to. // This also represents the a case that you can write to the // struct without detecting it. HRESULT rslt = D3D11CreateDevice( null, D3D11_DRIVER_TYPE.HARDWARE, null, 0 | D3D11_CREATE_DEVICE.DEBUG, null, 0, D3D11_SDK_VERSION, device, &featureLevel, null); // post-blit case, works otherdevice = device; // gives me a copy of 'p' due to 'alias p this' ID3D11Device rawdevice = device; // assignment back the other direction is caught by opAssign // this is also the code path used if there are multiple COM // interfaces in the hierarchy (IUnknown->ID3D11Resource->ID3D11Texture) // and post-blit isn't used because the types are different. device = rawdevice; My current version of ComPtr: struct ComPtr(T) { public: static assert(is(T : std.c.windows.com.IUnknown) || is(T : win32.unknwn.IUnknown)); T p; alias p this; private: this(T inPtr) { p = inPtr; } public: this(this) { if (p !is null) { p.AddRef(); } } ~this() { SafeRelease(); } // Attach and Detach set/unset the pointer without messing with the refcount (unlike opAssign assignment) void Attach(T other) { SafeRelease(); p = other; } T Detach() { T rval = p; p = null; return rval; } const bool HasData() { return (p !is null); } void opAssign(T other) { if (other !is null) { other.AddRef(); SafeRelease(); p = other; } else { SafeRelease(); } } void SafeRelease() { if (p !is null) { p.Release(); p = null; } } }
Getting function argument names?
I am working on a template class to provide function wrappers for COM based objects, so the calling code doesn't have to dereference the underlying pointer. In C++ we get this behavior for 'free' by overloading operator->. In D I can create a fairly funky mixin template to inspect the contained class and auto-generate a bunch of wrapper functions. Its easy enough to get the function list, by looping on __traits(getVirtualFunctions) for a class type, and feeding the results into MemberFunctionsTuple!(). This needs to be followed up by repeating the process for each base class specified , via BaseClassesTuple!(). So the real question: Is there any way to get to the friendly names for function arguments discovered through the traits system? MemberFunctionsTuple!() only returns the types as far as i can tell, which technically is enough for me to automatically name them something boring ArgA ArgB ArgC procedurally, is not a very nice thing to look at.
accessing your scope for template metaprogramming ?
Is there any way to access the your current scope? For instance the following pseudocode is what I am after more or less: class Foo { alias byte function(int) BarCompatibleInterface; byte Bar(int) { static assert(is(typeof(localscope) == function)); static assert(is(std.traits.ReturnType!(localscope) == std.traits.ReturnType!(BarCompatibleInterface)); static assert(is(std.traits.ParameterTypeTuple!(localscope) == std.traits.ParameterTypeTuple!(BarCompatibleInterface)); static assert(is(typeof(localscope.outer) == class)); static assert(is(typeof(localscope.outer.outer) == module)); } } My desire for this is to help the compiler generate better error messages from compilation of string mixins, as they could access the function and/or class they are in and give a better error message from within a static assert() construct.
COM objects
I need some insight into how COM objects interoperate with D, as well as some advice on how to manage them properly. I've seen posts that IUnknown is treated specialy by the compiler, what is the nature of this behavior? Does this include any kind of AddRef/Release behavior integration with the GC system or variable assignment, or is it purely for making interfaces have compatible vtbl's? If the AddRef/Release management isn't automatic is there a library somewhere to help with it (i.e. a D version of ATL's CComPtr template, or code similar to it)? I suspect the answers are somewhere I'm just not familiar with the extra libraries on dsource at the moment :)