AWS update-route53

May be you are also hosting own DNS zones on AWS and have ever asked yourselves how to keep the IP for an A record uptodate if your provided is giving you only a dynamic ip. Than you can have a look in the script update-route53.sh at

https://gitlab.com/mueli/aws

I have named the repository AWS by intention. I assume that I will maybe have more scripts to share in future … let’s see.

Move remote git repository

If you want to migrate all branches and tags you should use the following commands:

git clone --mirror $url

to clone the old $repo with all branches

cd $repo.git
git remote add $remote_name $remote_url

to setup a new remote

git push -f --tags $remote_name refs/heads/*:refs/heads/*

to push all refs under refs/heads (which is probably what you want)

type or non-type – that’s the question!

I had a really new but very interesting compiling issue these days. Let’s see the following construct:

#include <iostream>
#include <vector>

//------------------------------------------------------------------
template<class T>
class A {
public:
  A();
};

//------------------------------------------------------------------
template<class T>
A<T>::A()
{
  std::vector<T*>::iterator iter;
}

//------------------------------------------------------------------
int main() {
  std::cout << "Test template issues" << std::endl;
  A<unsigned> a;
  return( 0 );
}

That’s what I’d expect to work and it even would with some compilers but not with gcc. The problem here is the question if std::vector<T*>::iterator is a type, a variable (member) or a function (method). We get the following error:

In constructor ‘A<T>::A()’:

error: expected `;' before ‘iter’

In constructor ‘A<T>::A() [with T = unsigned int]’:

error: dependent-name ‘std::vector<T*,std::allocator<T*>
>::iterator’ is parsed as a non-type, but instantiation yields
a type

note: say ‘typename std::vector<T*,std::allocator<T*>
>::iterator’ if a type is meant

The default behaviour is that the parser assumes it to be a non-type (he expects a member or a method). But during instantiation it proves to be wrong – std::vector<T*>::iterator is a type.

The situation is easy to resolve if we read the error message :) We have to declare the iterator like:

typename std::vector<T*>::iterator iter;

After knowing what problem I have I also found the right chapter in Stroustrup’s bible at C.13.5 Typename and Template (The C++ Programming Language – Bjarne Stroustrup)

Dynamic class parametrization in C++

Despite the fact that it’s not the best coding style sometimes the design is much more elegant if you could define class properties dynamically.

What do I mean by that? No member variables which might be defined at compile time and can be accessed in normal style but aggregated data of arbitrary type which has to be accessed through a special “key”. The disadvantage is of course the fact that you hardly depend on runtime type information. You do not have any type safety during compilation as the types aren’t fixed at compile time.

The design goal was to create something like the following:

MyClass my_class;
std::vector<int> a_vector;
int an_int = 0;

my_class.add("a_vector",a_vector);
my_class.add("an_int",an_int);

std::cout << my_class.get<std::vector>("a_vector") << std::endl;
std::cout << my_class.get<int>("an_int") << std::endl;

The best way for me was to implement this with the help of boost::any and here is my suggestion:

#include <map>
#include <iostream>
#include <string>

#include <boost/any.hpp>

//------------------------------------------------------------------
struct AnyMap {
  void addAnyPair( const std::string& key , boost::any& value );

  template<typename T>
  T& get( const std::string key ) {
    return( boost::any_cast<T&>(map_[key]) );
  }

  std::map<const std::string, boost::any> map_;
};

void AnyMap::addAnyPair( const std::string& key , boost::any& value ) {
  map_.insert( std::make_pair( key, value ) );
}

//------------------------------------------------------------------
struct TestType {
  TestType():
    value_(3) {}

  void print() {
    std::cout << "We can call methods by reference! - value = " << value_ << std::endl;
  }

  int value_;
};

//------------------------------------------------------------------
int main()
{
  std::cout << "Dynamic class parametrization!" << std::endl;
  AnyMap any_map;

  std::string key = "key_1";
  boost::any value = 23;
  any_map.addAnyPair( key,value);
  key = "key_2";
  value = 45.3;
  any_map.addAnyPair( key,value);

  std::cout << "Retrieve int:    " << any_map.get<int>("key_1") << std::endl;
  std::cout << "Retrieve double: " << any_map.get<double>("key_2") << std::endl;
  any_map.get<int>("key_1") = 35;
  std::cout << "Modified value:  " << any_map.get<int>("key_1") << std::endl;

  key="key_3";
  boost::any test_type = TestType();
  any_map.addAnyPair(key,test_type);
  any_map.get<TestType>("key_3").print();
  any_map.get<TestType>("key_3").value_ = 5;
  any_map.get<TestType>("key_3").print();

  key="key_4";
  char* test_pointer = new char;
  *test_pointer = 'A';
  boost::any test_any_pointer(test_pointer);
  any_map.addAnyPair(key,test_any_pointer);
  std::cout << "Print pointer content: " << *any_map.get<char*>(key) << std::endl;
}