Stunt programming. Modern C++ is not about that.

User Manual

Contents

Due to a popular demand here is a short user manual on how to use "dbj  defval" Option 2.2 and Option 3.

First please recall the top of this article. We are using GDI+ to add some dose of reality to these usage examples.

#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
using namespace Gdiplus;
#pragma comment(lib, "Gdiplus.lib")

How to use Option 2.2

Declared as a “stunt” but of course, perfectly usable.

// assume it is in the 
// dbj::v_two namespace
using dbj::v_two::holder_maker;

// here we are inside some (named) namespace
// create processw wide default values holders
// creation happens on first call

// GDI+ default smoothness 
inline auto default_smoot = 
dbj::v_two::holder_maker(
SmoothingMode::SmoothingModeAntiAlias
);

// GDI+ default linecap's
inline auto default_lncap = 
dbj::v_two::holder_maker(
LineCap::LineCapRound
);

// just a default with 
inline auto default_width = 
    dbj::v_two::holder_maker(10);

inline void test_dbj_defval_option_two() {
// just get the dflt width
   auto dw0 = default_width();
   auto dw1 = default_width();
// somewhere and sometimes latter someone 
// might change the default value
// here is how
  auto dw2 = default_width(42);
}

You declare and define inside some namespace the global instances; after which callers from possible separate threads can use. Or change.

How to use Option 3

note: c++ anonymous name spaces make variables inside them to have internal linkage. To make sure things are not multiplied and instances are unique I very rarely use them. Please do use named name space’s around these examples.

// we assume: using namespace Gdiplus;
// 
struct S final {
mutable dbj::holder<REAL> width{ 0 };
S(REAL def_width) : width(def_width) {}
};
// to test the const behaviour
inline const S konst_{1024}; // initialized to 1024

// default process wide
// smoothness using GDI+ enum's
inline dbj::holder<SmoothingMode> smoothnes
{ SmoothingMode::SmoothingModeAntiAlias };

// default process wide 
// GDI+ line cap's
inline dbj::holder<LineCap> linecap
{ LineCap::LineCapRound };

inline void test_dbj_defval_option_three() {
// set the width to 512 for all the callers 
auto    width_ = konst_.width(512);
const   auto w1_ = konst_.width(); // 512
auto    w2_ = konst_.width(); // 512

_ASSERTE(width_ == 512);
_ASSERTE(w2_ == w1_ && w2_ == width_ && w1_ == width_);

//use the previosuly declared 
// and instantiated def val holders
auto lc_ = linecap();
auto sness = smoothnes();
}

You declare and define  dbj::holder<> instances as (c++17) inline globals. Then every caller from some thread uses them.  Please keep in mind calls above could be scattered across few threads, but that would make code longer and will obfuscate the usage pattern.

 

The C++ Tool
The C++ Tool