Main  /  Edit  /  History  /   /  Users Area

Coding Standards for CppCMS 1.x.x

Coding Style

General Coding Notes

Exceptions

All code you write should be exception safe. Only functions that you may assume they never throw exceptions are POSIX API or 3rd party C libraries like libgcrypy or sqlite3. Even STL may throw exception. Assume that std::bad_alloc may be thrown and handle it correctly.

Thus:

STL

Do not reinvent the wheel, use STL --- it is well document, well known, highly available library that does the job. Use it.

Notes:

  1. Always prefer std::vector to std::list --- it has better performance because it is cache friendly.
  2. Always prefer std:string for text storage.
  3. It is OK to return STL collections from functions, compiler know how to optimize them - return value optimization (RVO).
  4. Do not forget swap() function --- it can save lot's of unnecessary copies for you. For example:

     vector<char> foo();
     ...
     void bar() 
     {
        vector<char> s;
        for(;;) {
          // RVO
          vector<char> result = foo(); 
          // move
          s.swap(result);
          if(s.empty())
            break;
        }
     }
    

    Description: when you call s=foo() assignment operator is called that copies the value that foo() returned to s and then releases it. When you call s.swap(foo()) the value in s is replaced by returned value and the old value in s is cleaned --- you saved copy of probably huge buffer, you operation is done in O(1).

  5. If you have non-copyable class, you can store it in STL collection using reference counting pointer.

Libraries

Boost

CppCMS does not use Boost!

It uses either Booster library that uses Boost-Like API or it uses cppcms_boost - renamed Boost library hidden from the user deep inside.

Rationale:

Boost does not provide any backward compatibility between releases and tend to break something every three month.

And of course there is no even such thing like ABI compatibility when we talk about Boost.

So the only way to use it - use renamed cppcms_boost.

Booster

Booster is backward compatible, ABI stable CppCMS's Boost that can be and should be used in CppCMS's API.

It already has: aio (asio like library), threads, regex, function, POSIX-time, localization, smart_pointers, system, and logging library.

Of course it is only a small subset of what Boost provides but it covers 95% of what CppCMS needs from Boost. The rest can be found in hidden cppcms_boost namespace (see previous section)

Note. Booster is not exact subset of Boost as it re-implements some features in different way: Booster.Regex uses PCRE, AIO is quite different from Asio, Booster.Thread is build on top of pthreads library.

Also there are some libraries that not persistent or extremely different or simplified: Booster.Locale, Booster.Nowide, Booster.AIO, Booster.Log and so on.

The general rule of Booster - make API as similar as possible to Boost onces, but do it in simple and robust way.

Licenses

  1. All libraries should be OpenSource libraries
  2. Prefer non-copyleft licenses like MIT, 3 clause BSD, Boost over copyleft one, like LGPL.
  3. All libraries, CppCMS uses should be compatible with LGPLv3.
  4. You may use strong copyleft libraries for stand alone utilities that are not linked with CppCMS framework.

    For example: If you want to write GUI for cppcms_tcp_scale utility using Qt you are welcome.

Using

If you want to add an additional dependency for CppCMS make sure:

  1. Check if boost has implementation of such feature.
  2. There is a big value for adding such dependency.
  3. This library is highly available.
  4. You checked all alternatives and decided that this one is the best.
  5. You had added a CMake macro and conditional build for CppCMS that allows building all framework without this library.

For example, libgcrypt:

Keeping backward compatible ABI

One of the major goals of CppCMS is keeping stable backward compatible API and ABI the way it is done in Qt framework. This is not simple task to do in C++. So in order to achieve this goal following should be done:

  1. All user API should use only standard naively supported C++ classes and libraries -- STL.
  2. No 3rd part libraries API should be ever exposed to user -- including but not limited to -- Boost.
  3. All classes with exception of extremely simple ones with very limited and well defined functionality should include opaque pointer in order to ensure that adding or removing class member would break ABI.

This is a very good reference written for KDE on how not to break ABI. READ IT!!!

How to write classes

For example:

Header:

// foo.h
class foo : public booster::noncopyable {
public:
   foo(); // Always should be non-inlined constructor
   ~foo(); // Always should be non-inlined destructor
   int x() const; // getter
   void x(int );  // setter
private:
   struct data;
   booster::hold_ptr<data> d;   
};

Implementation:

// foo.cpp
struct foo::data {
    int x;
};

foo::foo() : d(new foo::data()) 
{
}
foo::~foo()
{
}
int foo::x() const { return d->x; }
void foo::x(int v) { d->x=v; }

F.A.Q.

  1. But how can I use (Put Boost Library Name) in the code?

    Use it, just never expose it in user API.

  2. What about boost::signal?

    Wrap a linked list of booster::function with your favorite API.

  3. What about boost::bind?

    Are you sure you need to use bind in headers?

    If so, there are simple member function binders implemented in mem_bind.h. If it not suit your needs just create simple copyable class with operator().

Internationalization and Localization

Keep in mind that this project should support many languages and cultures -- thus be aware of this.

The major gateway to localization facilities is std::locale class with custom facets assigned to http::context and to std::ostream of HTML output.

Be aware:

Other points:

Windows Specific Notes

Windows does not support UTF-8 codepage, so any-time you need to use system API you need to use so-called "Wide" API.

Of course neither C nor C++ standard does not provide such stuff like Wide API.

So, the policy is following:

Copyrights

I hope that someday this project would have commercial basis. In such case I need to have an ability to sub-license it. I do not mean that CppCMS may become closed sources project, it is and will remain FOSS framework with weak copyleft license like LGPL.

However for certain situation I would need an ability to provide additional licensing for this, like this is done by LGPL Qt4 and many other FOSS projects.

Thus every code contributed to CppCMS should hold at least one of the following conditions:

This would give CppCMS an opportunity to become successful FOSS project.

Clarification:

  1. I believe in Open Source and CppCMS would always be Free Software project.
  2. The CppCMS source code would be distributed under weak copyleft license allowing development of commercial software with CppCMS without fees.

Internals of CppCMS 1.x.x | Top

About

CppCMS is a web development framework for performance demanding applications.

Support This Project

SourceForge.net Logo

Поддержать проект

CppCMS needs You


Navigation

Main Page



Valid CSS | Valid XHTML 1.0