Thursday, March 12, 2015

Fun with variadic templates.

Tested with Ideone.com compiler with C++14 setting.
The WriteLn function presented here is based on one I found on CodeReview.

#include <fstream>
#include <iostream>
#include <utility>

auto WriteLn (std::ostream &os) -> std::ostream&
{
    os << "\n" ;
    return os ;
}

template <typename T, typename ... Args>
auto WriteLn (std::ostream &os, T first, Args&& ... args) -> std::ostream&
{
    os << first ;
    WriteLn (os, std::forward <Args> (args)...) ;
    return os ;
}

template <typename T1, typename T2>
auto sum (T1 t1, T2 t2) -> decltype (t1 + t2)
{
    return t1 + t2 ;
}

template <typename T, typename ... Args>
auto sum (T t, Args ... args) -> decltype (t + sum (args...))
{
    return t + sum (args...) ;
}

int main ()
{
    int x = 5 ;
   
    WriteLn (std::cout, "Hello. ", "\n", "x = ", x, ".") ;
    WriteLn (std::cout, sum (5.32, 1.1, 5)) ;
   
    return 0;
}


Thursday, February 12, 2015

2 to the power of N has X digits.

Tested with Visual Studio 2012

// std::pow (2, pow) has number_of_digits (pow) digits.
// Despite the recursive step, this is an O(1) operation.
auto number_of_digits (unsigned long long pow) -> unsigned long long
{
    if (pow < 4) {
        return 1 ;
    }

    else if (pow < 7) {
        return 2 ;
    }

    else if (pow < 10) {
        return 3 ;
    }

    else {
        unsigned long long n = pow / 10 ;
        unsigned long long least_significant_digit = pow - (n * 10) ;
        return n * 3 + number_of_digits (least_significant_digit) ;
    }
}


And here's a test Driver:

#include <iostream>

int main ()
{
    for (int n = 0; n < 10; ++n) {
        std::cout << "pow (2, " << n << ") has " << number_of_digits (n) << " digits." "\n" ;
    }

    for (int n = 10; n <= 100; n += 10) {
        std::cout << "pow (2, " << n << ") has " << number_of_digits (n) << " digits." "\n" ;
    }

    std::cout << "pow (2, 1000) has " << number_of_digits (1000) << " digits." "\n" ;
    std::cout << "pow (2, 1024) has " << number_of_digits (1024) << " digits." "\n" ;
    std::cout << "pow (2, 2000) has " << number_of_digits (2000) << " digits." "\n" ;
    std::cout << "pow (2, 2048) has " << number_of_digits (2048) << " digits." "\n" ;
   
    for (int n = 10000; n <= 100000; n += 10000) {
        std::cout << "pow (2, " << n << ") has " << number_of_digits (n) << " digits." "\n" ;
    }

    return 0 ;
}


If you want a templated version for some reason, you could try this:

#include <type_traits>

template <typename T>
auto number_of_digits (T pow)
    -> typename std::enable_if <std::is_integral <T>::value, T>::type
{
    if (pow <= 3) {
        return 1 ;
    }

    else if (pow <= 6) {
        return 2 ;
    }

    else if (pow <= 9) {
        return 3 ;
    }

    else {
        T n = pow / 10 ;
        T least_significant_digit = pow - (n * 10) ;
        return n * 3 + number_of_digits (least_significant_digit) ;
    }
}

Tuesday, December 16, 2014

Get input from console

If you don't want to trust user input, give this a try:

(Tested with Visual Studio 2012)

template <typename T>
auto GetInput (const std::string &strQuery) -> T
{
    std::cout << strQuery << "\n> " ;

    while (1) {
        T out = T () ;
        std::cin >> out ;

        if (std::cin.good () == false) {
            std::cin.clear () ;
            std::cin.ignore (std::numeric_limits <std::streamsize>::max (), '\n') ;
            std::cout << "Error!" "\n" ;
            std::cout << strQuery << "\n> " ;
            continue ;
        }

        return out ;
    }
}

The line:

auto GetInput (const std::string &strQuery) -> T

can be changed to:

 T GetInput (const std::string &strQuery)

for compilers that do not have C++11 features.

Wednesday, September 10, 2014

Output the source code of your file.

Here I output the source code for my program to the standard out descriptor.

#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>

template <class OutIter>
OutIter copy_file (const std::string &file_path, OutIter out) ;

int main ()
{
    std::string const path = __FILE__ ;
    copy_file (path, std::ostream_iterator <char> (std::cout)) ;

    return 0 ;
}

template <class OutIter>
OutIter copy_file (const std::string &file_path, OutIter out)
{
    std::ifstream file ;
    file.open (file_path) ;

    if (!file.good ()) {
        return out ;
    }

    file.unsetf (std::ios::skipws) ;

    auto begin = std::istream_iterator <char> (file) ;
    auto end = std::istream_iterator <char> () ;

    auto new_out = std::copy (begin, end, out) ;

    return new_out ;
}

Friday, August 8, 2014

Order of #include headers

First, I define four types of headers. These categories do not cover everything (such as .inl or .tpp, or whatever you want to call files that you may store templates in (I don't do this)).

1) Local Headers

These are usually headers you have created for your project.

IE

#include "TeddyBear.h

2) Third Party Libraries

These are libraries such as Boost or pugixml.

3) Standard Library

These are headers from the C or C++ Standard Library.

IE

#include <string>

4) Platform-specific libraries

These are libraries specific to your operating system.

IE

#include <windows.h>

I organize my headers in the order that I posted all of these categories. Within each category, I organize the headers alphabetically. Reasons why I organize them by these categories will be posted in the future (it's not just an arbitrary decision).

There are exceptions. On Windows, if you use pre-compiled headers (#include "stdafx.h"), you will need to put those at the top of your CPP files or else the compiler will cry.

Thursday, July 10, 2014

Imperative Spaghetti Programming

I was really bored one day and I decided to post this piece of art on Code Review. It is in the process of being deleted because it's too beautiful for the site.

Tested with Visual Studio 2012.

#include <iostream>
using namespace std ;

const int size = 3 ;
const char * names [] = {"Bob", "Alice", "Eve"} ;
int ages [] = {35, 28, 22} ;

int main (void)
{
    int *i = new int ;
    *i = 0 ;

    bool add_ages_please = true ;

Print:
    if (size <= *i) {
        if (add_ages_please)
            goto AddAges ;
            goto CleanUp ;
    }

    cout << names [*i] << " " << ages [*i] << "\n" ;
    ++(*i) ;
    goto Print ;

AddAges:
    --(*i) ;

    ages [*i] += 1 ;

    if (0 < *i) {
        goto AddAges ;
    }

    add_ages_please = false ;
    goto Print ;

CleanUp:
    delete i ;
    i = nullptr ;

    return 0 ;
}
 
"I use nothing but the very best modern
 programming practices. This is mission-critical production quality 
code. The fact that nobody has been able to suggest any improvements is a
 testament to its quality."

Modified Version of Russian Roulette

I feel like I found the base of this code so on some Powershell tutorial, but I'm not sure. Anyways, I've modified how the game plays out because I thought going from one chamber to the next was a bit boring. Instead, you rotate the barrel (or whatever you call it) to land on a random chamber. For the sake of the demo ending quickly, I made it so that it would always be a new random chamber that you did not previously land on.

I'll probably modify this a little bit to make it interactive and have multiple players playing. Then I'll post it on Code Review Stack Exchange.

Tested on Powershell v2

$seed = Get-Date
[int]$bullet_chamber = Get-Random -Minimum 1 -Maximum 6 -SetSeed $seed.Millisecond
[int]$trigger_pulls = 0
$vecChambers = New-Object System.Collections.ArrayList

for ($i = 0; $i -lt 6; $i++) {
    [void]$vecChambers.Add($i + 1)
}

Write-Host "Powershell Russian Roulette. The bullet is in chamber #$bullet_chamber."
Sleep -Seconds 2

while (1) {
    $trigger_pulls++
    [int]$vec_index = 0
   
    if ($vecChambers.Count -gt 1) {
        $vec_index = Get-Random -Maximum ($vecChambers.Count - 1)
    }
   
    [int]$nChamber = $vecChambers[$vec_index]
   
    Write-Host "Pulled the trigger on chamber #$nChamber!"
   
    if ($nChamber -eq $bullet_chamber) {
        Write-Host "Bang! You died after $trigger_pulls shots."
        break
    }
   
    else {
        Write-Host "You survived this time."
        $vecChambers.RemoveRange($vec_index, 1)
    }
   
    Sleep -Seconds 2 
}