Friday, February 10, 2012

Mericurial and merging with vim

My .hgrc

[ui]
username = Arun Chandrasekaran
editor = vim
merge = meld

[auth]
abc.prefix = 
abc.username = visionofarun@gmail.com
abc.password = abcd
abc.schemes = http https

[merge-tools]
meld.args = $local $other $base
meld.priority = 1

[diff]
ignorews = true
ignorewsamount = true
ignoreblanklines = true

[alias]
latest = log --limit 5

[extensions]
extdiff =
graphlog =
color =
fetch =
churn =

[extdiff]
cmd.meld =
cmd.vimdiff =

[alias]
vi = gvimdiff
vim = gvimdiff

When obtaining the diff (do) or putting the diff (dp) vim will throw this error:
"E101: more than two buffers in diff mode, don't know which one to use".

In such cases, use
:diffget 2
to get from the 2nd buffer and so on.

Saturday, January 07, 2012

Singleton in a header only library

Static member variables are inevitable in singleton implementations. If we define the static member variable in the header file and include it in more than one source file, the linker would throw multiple definition errors when trying to link the translation units. So it is a little tricky to design the singleton in header only implementations. Nevertheless it is not difficult.

C++ allows static members variables of class templates to be defined in more than one translation unit. The linker would merge multiple definitions into one. This is found abundant in the Boost library.

If we don't want to use the templates, but stick with the definite class approach, then this is one way to achieve singleton in the header only library implementation.

Log.hpp - This provides a singleton logger instance.
#include 
#include 

namespace Home { namespace Arun {

class Log
{
public:
    static void Init(std::string& logPath, std::string& logFilename,
                     int32_t maxFileSize);
    static Log* Instance();
    static void Destroy();

private:
    static Log* MyInstance(Log* pLog);

    Log(std::string& logPath, std::string& logFilename, int32_t maxFileSize) :
        m_logPath(logPath),
        m_logFile(logFilename),
        m_maxSize(maxFileSize)
    { }

    ~Log()
    { }

    Log(const Log& log);
    Log operator=(const Log& log);

    std::string m_logPath;
    std::string m_logFile;
    int32_t m_maxSize;
};

inline void Log::Init(std::string& logPath, std::string& logFilename,
                      int32_t maxFileSize)
{
    Log* ptr = new Log(logPath, logFilename, maxFileSize);
    MyInstance(ptr);
}

inline Log* Log::Instance()
{
    return MyInstance(NULL);
}

inline Log* Log::MyInstance(Log* ptr)
{
    static Log* myInstance = NULL;
    if (ptr)
        myInstance = ptr;
    return myInstance;
}

inline void Log::Destroy()
{
    Log* pLog = MyInstance(NULL);
    if (pLog)
        delete pLog;
}

} }

Log.cpp - A sample usage of the above library
#include "Log.hpp"

using namespace Home::Arun;

int main()
{
    std::string logPath = ".";
    std::string logFile = "Test.log";
    Log::Init(logPath, logFile, 1024*1024);
    Log* pLogInst = Log::Instance();
    std::cout << pLogInst << std::endl;
    Log::Destroy();
}