Monday, November 30, 2009

C++: compile time square root (sqrt) using templates

This code computes square root in compile time using C++ templates and binary search:


#include <iostream>
using namespace std;

#define MID(a, b) ((a+b)/2)
#define POW(a) (a*a)

template<int res, int l = 1, int r = res>
class SQRT;

template<int res, int r>
class SQRT<res, r, r> {
  public:
   static const int value = r;
};

template <int res, int l, int r>
class SQRT {
  public:
   static const int value = SQRT<res, (POW(MID(r, l)) >= res ? l : MID(r, l)+1), (POW(MID(r, l)) >= res ? MID(r, l) : r)>::value;
};

int main() {
  cout << SQRT<256>::value << endl;
  return 0;
}


See codepad paste for more information.

Thanks HELLER[i] for idea.

Sunday, November 22, 2009

C++: what is difference between "new T" from "new T()"

Recently I received an interesting question: what difference between "new T" from "new T()" in C++?

Let's look at example:

#include
#include
using namespace std;

class ST {
  public:
    ST() {
      cout << "ST constructor executed" << endl;
    }
};

class T {
  public:
    int i;
    ST st;
};

int main() {
  char mem[1000];
  T *t_ptr;

  memset(mem, 0x0F, sizeof(mem));
  t_ptr = new(mem) T;
  cout << "new T: " << int(t_ptr->i) << endl;

  memset(mem, 0x0F, sizeof(mem));
  t_ptr = new(mem) T();
  cout << "new T(): " << int(t_ptr->i) << endl;

  T t;
  cout << "T t: " << int(t.i) << endl;

  t = T();
  cout << "t = T(): " << int(t.i) << endl;

  return 0;
}


Output is:

ST constructor executed
new T: 252645135
ST constructor executed
new T(): 0
ST constructor executed
T t: 134515321
ST constructor executed
t = T(): 0


When we use "new T" and "T t" form, t-object default-initialized (in our example via default constructor). In C++ for backward compatibility with C default constructor initialize only non-POD class members. Therefore, called ST constructor and 'i' not initialized.

In case with "new T()" and "t = T()" we get value-initialized object. In our example each class member initialized separately.

For more information read this quotes from the C++ standard (ANSI ISO IEC 14882 2003):
A new-expression that creates an object of type T initializes that object as follows:
  • If the new-initializer is omitted:
    • If T is a (possibly cv-qualified) non-POD class type (or array thereof), the object is default-initialized (8.5). If T is a const-qualified type, the underlying class type shall have a user-declared default constructor.
    • Otherwise, the object created has indeterminate value. If T is a const-qualified type, or a (possibly cv-qualified) POD class type (or array thereof) containing (directly or indirectly) a member of const-qualified type, the program is ill-formed;
  • If the new-initializer is of the form (), the item is value-initialized (8.5);
  • If the new-initializer is of the form (expression-list) and T is a class type, the appropriate constructor is called, using expression-list as the arguments (8.5);
  • If the new-initializer is of the form (expression-list) and T is an arithmetic, enumeration, pointer, or pointer-to-member type and expression-list comprises exactly one expression, then the object is initialized to the (possibly converted) value of the expression (8.5);
  • Otherwise the new-expression is ill-formed.
(5.4.3. New, page 82)


To zero-initialize an object of type T means:
  • if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
  • if T is a non-union class type, each nonstatic data member and each base-class subobject is zero-initialized;
  • if T is a union type, the object’s first named data member89) is zero-initialized;
  • if T is an array type, each element is zero-initialized;
  • if T is a reference type, no initialization is performed.
To default-initialize an object of type T means:
  • if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
  • if T is an array type, each element is default-initialized;
  • otherwise, the object is zero-initialized.
To value-initialize an object of type T means:
  • if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
  • if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
  • if T is an array type, then each element is value-initialized;
  • otherwise, the object is zero-initialized.
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.

(8.5. Initializers, page 145)

Sunday, November 15, 2009

Python in science

Guido van Rossum wrote a very useful post about python tools in science:
Neopythonic: Python in the Scientific World

I'll research the languages and their libraries for my project work. Perhaps it would be python.

Wednesday, November 4, 2009

OpenSIPS 1.6 available on Fedora

OpenSIPS (former OpenSER) is fastest open source implementation of a SIP proxy.

Recently I added new rpm-package opensips-1.6 to fedora. OpenSIPS can be installed parallel with current openser package. At the moment package is pending to adding to updates for F-11.
https://admin.fedoraproject.org/pkgdb/packages/name/opensips

 
People who want to use db_oracle module should to install proprietary instantclient-sdk-10.2.0.3 from Oracle and to rebuild package with --with-oracle rpmbuild option. Then opensips-oracle rpm package will be available to install.

Thanks Peter Lemenkov for  help and package review.

UPD: package is pushed  to stable updates.