I was playing with DETS and I kept getting weird { error, { bad_object_header, * } } without understanding what was going on.

The table got broken permanently after the fact, but only one process was accessing the table so it wasn't a race.

Apparently if you use a tuple as key and you have differing shapes of it as key the table gets broken permanently.

So if you use as key { 1, 2 } and { 1, 2, 3 } you'll get a broken table, although you could use { 1, 2 } and { 1, { 2, 3 } }, and probably { { 1, 2 } } and { { 1, 2, 3 } }.

If you use asynchronous mode, everything works properly, the more you know.


My life is currently at its peak, the years of work have finally come to realize what I wanted to achieve.

For the past years I've been releasing most of my software under WTFPL, I'm probably the programmer with most projects under said license on this planet, but that aside, why did I choose WTFPL?

I could talk about the ethical reasoning behind it and the freedom the WTFPL gives to the user and other programmers, but no, the main reason for the choice is to cause butthurt. Sweet and lifelong butthurt.

Why? You may ask. Well, I release a lot of software, for free, anyone can use it, the only thing I want back is some irritation.

Licenses as fathers

At first it came from it being insulting to the free software movement, but it wasn't what I was going for.

I was going for companies not being able to use my software because of the license for various reasons, the one I hope for most is it containing non-professional language.

You may wonder why foul language in the license text would hinder such a thing, I mean, nobody forces them to read the LICENSE file all day.

Well, I, as a great man, put the license header in every single source file as the FSF advices to do.

The most hilarious part is they could rerelease my software under another license without getting into any legal troubles, in the end they can do what the fuck they want to with it.

But see, it's a hassle to mass edit all sources, and to maintain such edits when I release fixes or add features.

+ meh`: can you release your stuff under the MIT license?
+ oracle doesn't like the DWTFYW license
+ DWTFYWTPL*
- and I don't like Oracle

Of all companies I never thought I could be trolling Oracle, I don't know if it's for legal swamp land (it's an FSF approved license), or for foul language, but sincerely I don't care, I hate Oracle.

And I'm sorry developer that fell in my trap, I never meant to hurt you, only to bother you to some extent, and I thank you from the bottom of my heart, you made meh very happy.

PS: I'll never stop using the WTFPL.


Tabs? Spaces? Use both! [June 05, 2013]

Tabs! Spaces! Both?

No, really, use both, tabs for indentation and spaces for alignment, if you do anything else you're truly worse than Hitler.


Ruby inspect in C++ [March 17, 2013]

From the previous post about stringifying things, comes inspect, it's an improved version of stringify and actually returns inspecting strings like Ruby does, so it's not for stringifying, you should use an internal standard for that and use the appropriate methods and functions.

If you really want to just stringify things you can easily adapt inspect to do your biddings, it's WTFPL: do what the fuck you want with it.

It works on Clang, GCC and *gasp* MSVC.


Stringify all things in C++ [March 13, 2013]

While working on amirite I needed a nice way to print strings from any kind of incoming data to make assertions look decent, here goes nothing:

namespace stringify
{
# ifndef NO_DEMANGLE
#   include <cxxabi.h>

    template <typename Type>
    std::string
    type (void)
    {
      std::string result;
      int         status;
      char*       demangled = abi::__cxa_demangle(typeid(Type).name(),
                                                    nullptr, nullptr, &status);

      result = demangled;
      free(demangled);

      return result;
    }
# else
    template <typename Type>
    std::string
    type (void)
    {
      return typeid(Type).name();
    }
# endif

  namespace _has_cout
  {
    typedef char no[1];
    typedef char yes[2];

    struct any
    {
      template <typename T>
      any (T const&);
    };

    no& operator << (std::ostream const&, any const&);

    yes& test (std::ostream&);
    no&  test (no&);

    template <typename Type>
    struct has_cout
    {
      static std::ostream& s;
      static Type const& t;
      static bool const value = sizeof(test(s << t)) == sizeof(yes);
    };
  }

  template <typename Type>
  struct has_cout : _has_cout::has_cout<Type>
  {};

  template <typename Type>
  struct has_to_string
  {
    typedef char no[1];
    typedef char yes[2];

    template <typename C>
    static typename std::enable_if<std::is_same<decltype(&C::to_string),
                                   std::string(C::*)(void)>::value, yes&>::type
    test (decltype(&C::to_string));

    template <typename C>
    static no& test (...);

    static const bool value = sizeof(test<Type>(0)) == sizeof(yes);
  };

  template <typename Type>
  struct is_string
  {
    static const bool value = std::is_same<Type, std::string>::value ||
                              std::is_same<Type, std::wstring>::value ||
                              std::is_same<Type, std::u16string>::value ||
                              std::is_same<Type, std::u32string>::value;
  };

  template <typename Type>
  struct is_raw_string
  {
    static const bool value = (std::is_array<Type>::value &&
      std::is_same<typename std::remove_const<
        typename std::remove_extent<Type>::type>::type, char>::value) ||

      (std::is_pointer<Type>::value &&
        std::is_same<typename std::remove_const<
          typename std::remove_pointer<Type>::type>::type, char>::value);
  };

  template <typename Type>
  typename std::enable_if<is_string<Type>::value, Type>::type
  value (Type& value)
  {
    return value;
  }

  template <typename Type>
  typename std::enable_if<is_raw_string<Type>::value, std::string>::type
  value (Type& value)
  {
    return value;
  }

  template <typename Type>
  typename std::enable_if<std::is_fundamental<Type>::value, std::string>::type
  value (Type value)
  {
    std::ostringstream ss(std::ostringstream::out);
    ss << std::boolalpha << value;

    return ss.str();
  }

  template <typename Type>
  typename std::enable_if<std::is_pointer<Type>::value &&
    !is_raw_string<Type>::value, std::string>::type
  value (Type& value)
  {
    std::ostringstream ss(std::ostringstream::out);
    ss << "(" << type<Type>() << ") " << value;

    return ss.str();
  }

  template <typename Type>
  typename std::enable_if<std::is_enum<Type>::value &&
    has_cout<Type>::value, std::string>::type
  value (Type value)
  {
    std::ostringstream ss(std::ostringstream::out);
    ss << "#<enum " << type<Type>() << ": " << value << ">";

    return ss.str();
  }

  template <typename Type>
  typename std::enable_if<std::is_enum<Type>::value &&
    !has_cout<Type>::value, std::string>::type
  value (Type value)
  {
    std::ostringstream ss(std::ostringstream::out);
    ss << "#<enum " << type<Type>() << ": " <<
      static_cast<typename std::underlying_type<Type>::type>(value) << ">";

    return ss.str();
  }

  template <typename Type>
  typename std::enable_if<std::is_union<Type>::value &&
    has_cout<Type>::value, std::string>::type
  value (Type& value)
  {
    std::ostringstream ss(std::ostringstream::out);
    ss << "#<union " << type<Type>() << ": " << value << ">";

    return ss.str();
  }

  template <typename Type>
  typename std::enable_if<std::is_union<Type>::value &&
    !has_cout<Type>::value, std::string>::type
  value (Type& value)
  {
    std::ostringstream ss(std::ostringstream::out);
    ss << "#<union " << type<Type>() << ":" << &value << ">";

    return ss.str();
  }

  template <typename Type>
  typename std::enable_if<std::is_class<Type>::value &&
    !is_string<Type>::value &&
    !has_to_string<Type>::value &&
    has_cout<Type>::value, std::string>::type
  value (Type& value)
  {
    std::ostringstream ss(std::ostringstream::out);
    ss << "#<" << type<Type>() << ": " << value << ">";

    return ss.str();
  }

  template <typename Type>
  typename std::enable_if<std::is_class<Type>::value &&
    !has_to_string<Type>::value &&
    !is_string<Type>::value &&
    !has_cout<Type>::value, std::string>::type
  value (Type& value)
  {
    std::ostringstream ss(std::ostringstream::out);
    ss << "#<" << type<Type>() << ":" << &value << ">";

    return ss.str();
  }

  template <typename Type>
  typename std::enable_if<has_to_string<Type>::value, std::string>::type
  value (Type& value)
  {
    return value.to_string();
  }

  template <typename Type>
  typename std::enable_if<std::is_array<Type>::value &&
    !is_raw_string<Type>::value, std::string>::type
  value (Type& value)
  {
    std::ostringstream ss(std::ostringstream::out);

    ss << "[";
    for (unsigned i = 0; i < std::extent<Type>::value; i++) {
      ss << stringify::value(value[i]);

      if (i < std::extent<Type>::value - 1) {
        ss << ", ";
      }
    }
    ss << "]";

    return ss.str();
  }
}

An example stringifying things:

class foo
{};

class bar
{
  public:
    std::string
    to_string (void)
    {
      return "#<bar: dabbah>";
    }
};

enum class derp
{
  lol, wut, omg
};

std::ostream& operator << (std::ostream& on, derp v)
{
  switch (v) {
    case derp::lol:
      on << "lol";
      break;

    case derp::wut:
      on << "wut";
      break;

    case derp::omg:
      on << "omg";
      break;
  }

  return on;
}

int
main (int argc, char* argv[])
{
  std::string str = "34";
  std::cout << stringify::value(str) << std::endl;

  foo a;
  std::cout << stringify::value(a) << std::endl;

  bar b;
  std::cout << stringify::value(b) << std::endl;

  std::cout << stringify::value(23) << std::endl;
  std::cout << stringify::value(derp::omg) << std::endl;

  int lol[][2] = { { 1, 2 }, { 3, 4 } };
  std::cout << stringify::value(lol) << std::endl;

  float* duh = (float*) 342;
  std::cout << stringify::value(duh) << std::endl;

  std::cout << stringify::value("lol") << std::endl;

  std::cout << stringify::value(true) << std::endl;

  return 0;
}

And the output:

34
#<foo:0x7fff253f8730>
#<bar: dabbah>
23
#<enum derp: omg>
[[1, 2], [3, 4]]
(float*) 0x156
lol
true

Bam, magic (as usual).