Binglong's space

Random notes on computer, phone, and life

Antenna Impedance and Transmission Lines

Posted by binglongx on July 13, 2015

[memo]

See antenna-theory.com

Posted in Amateur Radio | Tagged: , , , , , , | Leave a Comment »

Windows 10 Insider Preview on VirtualBox

Posted by binglongx on June 29, 2015

I downloaded Windows 10 Preview through Windows Insider Program. With Oracle VirtualBox at my disposal, I can install Windows 10 Preview as a guest OS in the virtual machine and have a quick impression on Windows 10 without risking my current working system.

Install Windows 10 in VirtualBox

This is what I did to setup a virtual machine.

  • Download Windows 10 Preview ISO file. I use the 64-bit version Windows10_InsiderPreview_x64_EN-US_10130.iso.
  • Make sure you installed latest VirtualBox. I have VirtualBox 4.2.16 (x64) on my Windows 8.1 x64.
  • In VirtualBox, click New button (or Machine | New… menu item). This brings the Create Virtual Machine dialog box.
  • I choose the machine Name Windows10Preview, Type Microsoft Windows, and Version Windows 8.1 (64-bit). My VirtualBox does not directly support Windows 10 yet, so pretend to be Windows 8.1 for now. I tried Other Windows and the virtual machine would not boot.

image

  • Go through other regular settings, including Enable 3D Acceleration and Enable 2D Video Acceleration, and create the virtual machine. Then select the virtual machine, choose Settings | Storage, for Controller: IDE, mount the downloaded ISO as the CD drive. This is to let installer in the ISO run and install Windows 10 to the virtual machine when it boots.

image

  • Now start the virtual machine in VirtualBox. Go through the Windows installation routine. Eventually, you arrive at Windows 10:

image

That’s quite smooth.

You can unmount the ISO file from the IDE CD drive of the virtual machine now.

Change Screen Resolution for Windows 10 Virtual Machine

Due to the fact that Windows 10 is not natively supported by my VirtualBox, there is an immediate annoyance. The guest Windows 10 box has very limited choices for its screen resolution. My physical display is 1920×1080, but the Windows 10’s Microsoft Basic Display Adaptor only support video modes like, 640×480, 800×600, 1024×768, 1152×864, 1280×1024, and 1600×1200. None of them is suitable for my display.

Following the guide here, this is how I changed the screen resolution to match my display.

  • Shut down Windows 10 virtual machine if it was not.
  • Make sure that virtual machine is selected in VirtualBox, but not started:

image

  • In the host Windows system, run cmd.exe to open up a command line console window. Change directory to the VirtualBox installation directory (C:\Program Files\Oracle\VirtualBox on my Windows 8.1 x64), then run command VBoxManage.exe setextradata to add a custom video mode to the guest virtual machine you created. You can use VBoxManage.exe getextradata to verify the virtual machine has the data you set. This is what I run for my virtual machine “Windows10Preview”:
cd "C:\Program Files\Oracle\VirtualBox"
VBoxManage.exe setextradata "Windows10Preview" CustomVideoMode1 1920x1080x32
VBoxManage.exe getextradata "Windows10Preview" CustomVideoMode1
VBoxManage.exe getextradata "Windows10Preview" enumerate
  • This is a screenshot of my command line window:

image

  • Now start the virtual machine in VirtualBox. Go to Display Settings, you will find that the new resolution is available:

image

  • If you dig deeper, you can list all modes in the Microsoft Basic Display Adapter, and find the new resolution there:

image

  • Use that resolution, and the screen looks much better:

image

Conclusion

It’s quite easy to install Windows 10 Preview in VirtualBox, and following a few steps the virtual Windows 10 can use the full physical display resolution. I think a later version of VirtualBox will make this much easier.

Posted in Computer and Internet | Tagged: , , , , , , , , , , , | Leave a Comment »

Parsing Text File with Lines Like “Key=Value”

Posted by binglongx on June 24, 2015

See code below:

#include <cctype>           // isspace
#include <cstring>          // strlen
#include <fstream>          // std::ifstream
#include <string>           // std::string
#include <unordered_set>    // std::unordered_set
#include <unordered_map>    // std::unordered_map
#include <algorithm>        // std::find_if
#include <iostream>         // std::cout

// trim spaces from left side of string
void trim_left(std::string& s)
{
    s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](char ch){ return !isspace(ch); }));
}

// trim spaces from right side of string
void trim_right(std::string& s)
{
    s.erase(std::find_if(s.rbegin(), s.rend(), [](char ch){ return !isspace(ch); }).base(), s.end());
}

// trim spaces from both sides of string
void trim(std::string& s)
{
    trim_right(s);
    trim_left(s);
}

// parse the text file for key = value lines, and result will have the key-value pairs.
//   if keys is not empty, only those are recognized keys;
//   if keys is empty, all key = value lines with non-empty key are recognized
// make sure max_line_len is big enough for longest lines in the text file.
// return false if file cannot be opened or line buffer is not big enough
bool parse(const char* filename, const std::unordered_set<std::string>& keys, 
            std::unordered_map<std::string, std::string>& result, size_t max_line_len)
{
    std::ifstream f(filename);
    if (!f.good())
        return false;
    
    result.clear();
    std::string line;
    for (;;)
    {
        line.resize(max_line_len);  // with supposedly enough buffer size
        f.getline(&line[0], (std::streamsize)(line.size()));
        if (f.eof())
            break;
        if (f.fail())
            return false;   // something wrong - line buffer is too small.

        // shrink to actual size so line is an exact string of the line, even for empty line.
        line.resize(strlen(&line[0]));
        //std::cout << "Line read" << ": " << line << std::endl;
        auto eq = line.find('=');
        if (line.npos != eq)
        {
            // '=' found in line
            auto key = line.substr(0, eq);
            trim(key);
            if (!key.empty() && (keys.empty() || keys.count(key)>0) )
            {
                auto val = line.substr(eq + 1);
                trim(val);
                //std::cout<<" entry found"<<": key = "<<key<<"; value = "<<val<< std::endl;
                result[key] = val;
            }
        }
    }
    return true;
}

// a test function
void test_parse(const char* filename, const std::unordered_set<std::string>& keys)
{
    std::cout << "Filename: " << filename << std::endl;
    if (!keys.empty())
    {
        std::cout << "Parse with only these allowed keys:" << std::endl;
        std::cout << "  ";
        for (auto& key : keys)
            std::cout << key << " ";
        std::cout << std::endl;
    }
    else
        std::cout << "Parse allowing any keys" << std::endl;
    std::cout << "All other lines are ignored." << std::endl;
    
    std::unordered_map<std::string, std::string> result;
    size_t max_line_len = 1024;
    if (parse(filename, keys, result, max_line_len))
    {
        std::cout << "Result:" << std::endl;
        for (auto& kv : result) // print result:
            std::cout << "  " << kv.first << " = " << kv.second << std::endl;
    }
    else
        std::cout << "Error: Invalid file or there is a line that is too long"
          << ", larger than " << max_line_len << " characters." << std::endl;
}

// test parse()
int main()
{
    test_parse("no_such_filename", std::unordered_set<std::string>{});
    std::cout << std::endl;
    test_parse("C:\\Temp\\a.txt", std::unordered_set<std::string>{"ch0", "ch1", "ch2"});
    std::cout << std::endl;
    test_parse("C:\\Temp\\a.txt", std::unordered_set<std::string>{});

    return 0;
}

The parse() function can parse using predefined keys such that only lines with these keys are taken, or it takes any key=value lines when there is no predefined keys.

This is the text file a.txt used in the test:

Line0
Line 1

Line = 3
ch0 = a.data 
Line5
      ch1 =    b.data      
ch2= c.data
  Build config: Release
[ !PASSED! ] 2 tests
---===
#REPORT: 20141210181006 FILTERED 10847 0 2 2 2 0

This is the running result:

Filename: no_such_filename
Parse allowing any keys
All other lines are ignored.
Error: Invalid file or there is a line that is too long, larger than 1024 characters.

Filename: C:\Temp\a.txt
Parse with only these allowed keys:
  ch0 ch1 ch2
All other lines are ignored.
Result:
  ch0 = a.data
  ch1 = b.data
  ch2 = c.data

Filename: C:\Temp\a.txt
Parse allowing any keys
All other lines are ignored.
Result:
  Line = 3
  ch0 = a.data
  ch1 = b.data
  ch2 = c.data
  --- = ==

Posted in C++ | Tagged: , , , , , , , , , , | Leave a Comment »

Aukey Turbo Charger PA-U28 Impression

Posted by binglongx on June 7, 2015

As mentioned in an earlier post, Aukey Turbo Charger PA-U28 is a USB charger that supports Qualcomm Quick Charge 2.0 (QC2.0). This means it can charge QC2.0 compatible devices much faster, such as Moto X 2nd generation (Moto X2) phone.

The original wall charger coming with Moto X2 (rated 5.0V/1150mA) charges Moto X2 rather slowly. This is one measured example:

Charging Time (minutes) Battery Level
+  0 4%
+ 20 23%
+ 30 32%
+ 87 83%
+128 99%

On contrast, the Aukey Turbo Charger charges much faster. This is one measured example:

Charging Time (minutes) Battery Level
+  0 5%
+ 20 42%
+ 45 72%

In both examples, the Moto X2 phone was idle with Wi-Fi on while charging.

Aukey QC charger charges the phone much faster. When the battery level is low, it charges almost twice as fast as the factory non-QC charger (20 minutes to up the battery level by 37% vs. 19%). The phone was also hot when charged with Aukey charger; while it was not even warm when charged with the Moto X2 charger. When the battery level is higher, Aukey QC charger starts to slow down.

Posted in Computer and Internet | Tagged: , , , , , , , , | Leave a Comment »

Using Swap Properly in C++

Posted by binglongx on June 6, 2015

Introduction

In a previous post, the correct way to use swap is given in the example below:

#include <utility>  // access std::swap in C++11.  In C++03, use <algorithm>

void foo(T& a, T& b) 
{ 
    using std::swap;  // (1) 
    swap(a,b);        // (2) 
}

But why do we have Line (1) to introduce std::swap, and Line (2) to use an unqualified swap call?

Illustration Example

Let’s have a look at the code example below:

#include <iostream>

namespace ns
{
    class A {};

    void swap(A& a, A& b)
    {
        std::cout << "ns::swap()" << std::endl;
    }

    class B {};
}

namespace ste   // std, really!
{
    template<class T>
    void swap(T& a, T& b)
    {
        std::cout << "ste::swap()" << std::endl;
    }
}

int main()
{
    {
        ns::A a, b;
        swap(a, b);        // ns::swap()
    }
    {
        ns::B a, b;
        swap(a, b);        // compile error: no function match
    }
    {
        using ste::swap;
        ns::A a, b;
        swap(a, b);        // ns::swap()
    }
    {
        using ste::swap;
        ns::B a, b;
        swap(a, b);        // ste::swap()
    }

    return 0;
}

In namespace ns, classes A and B are defined, and a free swap function is defined only for A. In namespace ste, a function template swap is defined for arbitrary type. Notice that ste::swap is really meant for std::swap in the example. Even though namespace std houses a lot of C++ standard constructs, it is not treated specially by the compiler in this case. So using namespace ste would show the same idea here, without interfering with std stuff.

Now let’s look at the call sites.

In Lines 27-28, an unqualified swap is called on ns::A objects. According to Koenig Lookup(ADL) rules, here the compiler looks into namespace ns, where A is defined, and it finds the ns::swap(A&,A&) function.

In Lines 31-32, an unqualified swap is called on ns::B objects. According to Koenig Lookup rules, the compiler looks into namespace ns, where B is defined, but it cannot find an ns::swap function that takes B objects. Line 32 triggers a compile error.

In Lines 35-37, the using directive introduces the ste::swap name to the local scope, then an unqualified swap is called on ns::A objects. The Koenig Lookup is performed first (before trying ste::swap), so the call resolves to the ns::swap(A&,A&) function.

In Lines 40-42, the using directive introduces the ste::swap name to the local scope, then an unqualified swap is called on ns::B objects. The Koenig Lookup is performed first (before trying ste::swap), but it could not find any ns::swap function taking B objects. Then the compiler considers ste::swap, and it resolves to std::swap(), which is a function template and can take B objects.

Conclusion

It is clear that the proper approach to use swap ensures:

  • If there is a user defined swap function in the same namespace as the type is defined, ADL resolves the unqualified swap call to that function (and that’s what the user wants);
  • If user does not define a swap function in the same namespace as the type is defined, using std::swap directive would help to resolve the unqualified swap call to the standard library function template std::swap, therefore a default swap support is provided. It’s a different problem whether the default std::swap support is good for the user defined type; supposedly the user should provide the custom free swap function if the default swap function is not good for the type.

Posted in C++ | Tagged: , , , , , | 1 Comment »

Type Alias and Koenig Lookup

Posted by binglongx on June 5, 2015

Introduction

I have some code that is similar to this:

#include <iostream>

namespace implementation
{
    namespace win
    {
        class A{};
    }
    namespace posix
    {
        class A{};
    }
}

namespace ns
{
#ifdef _WIN32
    using A = implementation::win::A;
#else
    using A = implementation::posix::A;
#endif

    // dump ns::A to any stream
    template<class OStream>
    OStream& operator << (OStream& os, const A& a)
    {
        os << "A";    // fake
        return os;
    }
}

int main()
{
    ns::A a;
    std::cout << a;
    return 0;
}

In the implementation namespace, there are two different implementations of class A for Windows and POSIX. In the ns namespace, a type alias A is created to the appropriate A implementation depending on the building platform. At Line 24, a universal insert operation function is created for ns::A, such that I do not have to write the same function for both implementation::win::A and implementation::posix::A. All seems good.

Compile Error

But at Line 35, it does not compile. This is what ideone.com C++14 complains:

prog.cpp: In function 'int main()':
prog.cpp:35:15: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
  std::cout << a;
               ^
In file included from /usr/include/c++/4.9/iostream:39:0,
                 from prog.cpp:1:
/usr/include/c++/4.9/ostream:602:5: note: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = implementation::posix::A]'
     operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
     ^

And this is what Visual Studio 2013 complains:

1>prog.cpp(35): error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'ns::A' (or there is no acceptable conversion)
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(498): could be 'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::basic_streambuf<char,std::char_traits<char>> *)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(478): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(const void *)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(458): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(long double)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(438): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(double)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(418): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(float)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(397): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(unsigned __int64)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(377): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(__int64)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(356): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(unsigned long)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(336): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(long)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(316): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(unsigned int)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(291): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(int)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(271): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(unsigned short)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(237): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(short)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(217): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::_Bool)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(210): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::ios_base &(__cdecl *)(std::ios_base &))'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(203): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::basic_ios<char,std::char_traits<char>> &(__cdecl *)(std::basic_ios<char,std::char_traits<char>> &))'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(197): or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::basic_ostream<char,std::char_traits<char>> &(__cdecl *)(std::basic_ostream<char,std::char_traits<char>> &))'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(699): or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const char *)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(746): or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,char)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(784): or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const char *)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(831): or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,char)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(957): or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const signed char *)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(964): or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,signed char)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(971): or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const unsigned char *)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(978): or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,unsigned char)'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(988): or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<char,std::char_traits<char>,ns::A>(std::basic_ostream<char,std::char_traits<char>> &&,const _Ty &)'
1>          with
1>          [
1>              _Ty=ns::A
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(1026): or       'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const std::error_code &)'
1>          while trying to match the argument list '(std::ostream, ns::A)'

The error messages are a bit too much, but they tell the same thing: they cannot find a function that allows insertion of ns::A type object a into std::cout.

If I change the call site to explicitly pick the universal insert function by specifying its namespace, this works:

int main()
{
    ns::A a;
    //std::cout << a;
    ns::operator<<(std::cout, a);   // print "A"
    return 0;
}

Of course, this is not what I want, because the point of writing the insert operator overload function is to avoid explicit calling with ugly namespace.

Koenig Lookup

In general, Koenig Lookup, i.e., Argument Dependent Lookup (ADL), helps to find the function in the correct namespace when looking up unqualified function name. In addition to the usual namespaces, Koenig Lookup also considers the namespaces in which the types of the arguments are defined, when searching for the function. This is very useful for operator overload functions, as in the example above, because an overloaded operator is meant to called in its natural succinct form, not the namespace-raided form. But the rule also applies to any free function, not just operator overloads.

In the example above, although a is of type ns::A, its actual type is not. The real type of a is either implementation::win::A or implementation::posix::A. When ADL is in action, it ignores the C++11 type alias (or C++98 typedef) and directly considers only the namespace where the actual type is defined. The type alias (or typedef) is meant for people, not for compiler. In the example, the compiler uses ADL to search first the std namespace of the first argument std::cout. It could not find a match. So it searches the namespace of the type of the second argument a, i.e., implementation::win or implementation::posix. But of course it could not find any match for the insert operator there, hence the compile error.

Workaround 1

One way to solve the problem is to put the function back to the right namespace:

#include <iostream>

namespace implementation
{
    namespace win
    {
        class A{};

        // dump ns::A to any stream
        template<class OStream>
        OStream& operator << (OStream& os, const A& a)
        {
            os << "A";    // fake
            return os;
        }
    }
    namespace posix
    {
        class A{};

        // dump ns::A to any stream
        template<class OStream>
        OStream& operator << (OStream& os, const A& a)
        {
            os << "A";    // fake
            return os;
        }
    }
}

namespace ns
{
#ifdef _WIN32
    using A = implementation::win::A;
#else
    using A = implementation::posix::A;
#endif
}

int main()
{
    ns::A a;
    std::cout << a; // groovy!
    return 0;
}

This of course works. But my original goal was to reduce the duplication of the insert operator function.

Workaround 2

If I insist to have only one insert operator function for ns::A, I need to make ns::A a distinct type, not a type alias.

#include <iostream>

namespace implementation
{
    namespace win
    {
        class A{};
    }
    namespace posix
    {
        class A{};
    }
}

namespace ns
{
#ifdef _WIN32
    class A : public implementation::win::A{};
#else
    class A : public implementation::posix::A{};
#endif

    // dump ns::A to any stream
    template<class OStream>
    OStream& operator << (OStream& os, const A& a)
    {
        os << "A";    // fake
        return os;
    }
}

int main()
{
    ns::A a;
    std::cout << a; // groovy!
    return 0;
}

At Lines 18/20, I now create a new type ns::A using public inheritance with empty body. ns::A will have all the public interface elements that its implementation A type has, so the user would use it almost the same way it was intended. The only exceptions are the constructor functions – I will have to write some code in the empty class body such that ns::A can be constructed the same way its implementation could. If the work there is less than the body of the insert operation function, it is good to choose this workaround. Otherwise I would stay with Workaround 1.

Conclusion

Koenig Lookup does not apply for type aliases. Make sure it can resolve to your intended free function or operator overload function.

Posted in C++ | Tagged: , , , , , , , , | 1 Comment »

Posting Source Code to WordPress Using PreCode Plugin For Windows Live Writer

Posted by binglongx on May 31, 2015

As summarized in a past post, I have been using Source Code Highlighter for WordPress.com (which is a plugin for Windows Live Writer, i.e., WLW, my preferred blog writer) to post formatted source code to this WordPress.com blog. Over the years of blogging, I have used quite some different WLW source code plugins, see this for the what I tried:

image

The disabled plugins, including Code Snippet, Insert Code, Source Code, and VSPaste, all worked to some extent, but had different problems. Some of them create code blocks that appear pretty in one browser but absolutely ugly in another, or lack support for certain programming languages, and so on.

WordPress.com has built in support for posting source code. The WordPress.com supports posting source code through Alex Gorbatchev’s SyntaxHighlighter on its server side. Source Code Highlighter for WordPress.com plugin works fine for me because it sends the source code block following the SyntaxHighlighter convention, and the WordPress server serves the pages without compatibility problems for all browsers.

The Source Code Highlighter for WordPress.com plugin is however very simple, and does not use all the features of SyntaxHighlighter. This is the plugin in action:

image

For example, with this plugin, I cannot highlight a line in the source code block, which could be the focus of the discussion.

Today I got a chance to try PreCode, which is another WLW plugin for formatting source code, also following SyntaxHighlighter protocol and suitable for WordPress.com. It is very easy to install – you only need to download and run the .msi installer and restart WLW to use it.

Below is a test source code block in the PreCode plugin:

image

You can see there are a lot of options you can play with. Notice that I highlight Lines 7 and 15 in the source code.

And this is how it appears in the post:

#include <iostream>
#include <functional>
   
// the actual work is done in this function
template<class FunctionObject> void my_func(FunctionObject is_odd)
{
    int number = 12345;
    std::cout << number << " is : " << (is_odd(number) ? "odd" : "even") << std::endl;
}
   
// in C++98 you need to define a function object class potentially far away from calling site.
// Writing a dislodged class is inconvenient and hard to maintain!
struct IsOdd : public std::unary_function<int, bool> 
{
    bool operator() (int number) { return (number % 2 != 0); }
};
   
// C++98 calling site:
void foo()
{
    my_func(IsOdd());
}
   
// C++11 calling site:
void foo2()
{
    // a lambda is defined inline and passed down. No separate function object class definition necessary!
    my_func([](int number) { return (number % 2 != 0); });
}

So far I am very happy with PreCode.

Posted in Blogging | Tagged: , , , , , , , , , , , | 1 Comment »

Assign C++ Array

Posted by binglongx on May 28, 2015

Introduction

As discussed in a previous post C++ Array (1), the C++ standard does not allow you to directly assign an array. The following program does not compile:

int main() 
{
    const char a[10] = "abc";
    char b[10];
    b = a;		// compile error!
    return 0;
}

Assign Array via Struct

As the post also showed, if you put the array in a struct, assigning the struct is however possible, and it would in fact assign the array (assuming that assigning array means assigning array members). So this is a function that would perform array assignment through the struct member array hack:

#include <iostream>

template<typename T, size_t N>
void assign(T (&dst)[N], const T(&src)[N])
{
    using P = struct { T _[N]; };
    reinterpret_cast<P&>(dst) = reinterpret_cast<const P&>(src);
}

int main() 
{
    const char a[10] = "abc";
    char b[10];
    // b = a;		// compile error!
    assign(b, a);
    std::cout << b << std::endl;  // print "abc"
    return 0;
}

Notice that although the assign function involves reinterpret_cast, it is actually pretty safe to do so, as the struct with merely an array member of the same bound would have the same alignment and size as the naked bounded array.

The code above works with array of arbitrary type. For example:

#include <iostream>

template<typename T, size_t N>
void assign(T (&dst)[N], const T(&src)[N])
{
    using P = struct { T _[N]; };
    reinterpret_cast<P&>(dst) = reinterpret_cast<const P&>(src);
}

// struct with custom copy assignment operator
struct C
{
    C& operator = (const C&) { std::cout<<"C::=()"<<std::endl; }
};

int main() 
{
    const C a[3];
    C b[3];
    // b = a;		// compile error!
    assign(b, a);
    return 0;
}

The program above would print out:

C::=()
C::=()
C::=()

It is obvious that the compiler would in fact generate the code to call the copy assignment operator for each element in the array, and that’s why the program prints out those 3 lines.

Assign Array via for Loop

But why do I choose to implement the assign function as show above, instead of this one below?

template<typename T, size_t N>
void assign(T (&dst)[N], const T(&src)[N])
{
    for(size_t i=0; i<N; ++i)
        dst[i] = src[i];
}

Rest assured, the latter assign implementation works just fine as well.

I prefer the earlier implementation because I believe the compiler may have a better chance to optimize the assignment of the array embedded in a struct, than to optimize my hand written for loop. I also like that my code that has run-time behavior should be kept minimal: the earlier implementation has only one struct assignment operation to me, while the latter implementation involves a for loop, two element dereferences, and an assignment. I consider the type casts in the earlier implementation have no run-time impact. The idea of the earlier implementation is to let the compiler do as much heavy lifting as possible – it may produce something better than my hand written for loop.

Move Assignment

In fact, the default assignment of struct with a bounded array member supports not only copy assignment as shown above, but also move assignment:

#include <iostream>

// copy assignment
template<typename T, size_t N>
void assign(T (&dst)[N], const T(&src)[N])
{
    using P = struct { T _[N]; };
    reinterpret_cast<P&>(dst) = reinterpret_cast<const P&>(src);
}

// move assignment
template<typename T, size_t N>
void assign(T (&dst)[N], T(&&src)[N])
{
    using P = struct { T _[N]; };
    reinterpret_cast<P&>(dst) = reinterpret_cast<P&&>(src);
}

// struct with custom copy assignment operator
struct C
{
    C& operator = (const C&) { std::cout<<"C:: copy assignment"<<std::endl; }
    C& operator = (C&&)      { std::cout<<"C:: move assignment"<<std::endl; }
};

int main() 
{
    C a[3];
    C b[3];
    assign(b, a);
    assign(b, std::move(a));  // move assignment
    return 0;
}

The code above would print out:

C:: copy assignment
C:: copy assignment
C:: copy assignment
C:: move assignment
C:: move assignment
C:: move assignment

This basically means the elements are properly moved from the source array to the destination array.

Again, you can use a for loop to implement the move version of array assignment, but I consider the struct trick is more elegant.

Conclusion

It is shown that the struct hack can be used to trick the compiler to perform array assignment (either copy or move assignment) for us neatly.

In the end, it is not possible to overload = operator for array in C++. The = operator must be a member function of a class, and an array is not a class. So, to get the array assignment, you’ll need to write a function like the assign() ones in this post.

Posted in C++ | Tagged: , , , , , , , , , | Leave a Comment »

USB Chargers

Posted by binglongx on May 13, 2015

A Myriad of USB Chargers

With the popularity of microUSB based charging on latest smart phones, tablets, and even some 2-in-1 laptops/tablets, I have basically quite some chargers around in home. These chargers normally have a USB A female socket and use a USB to microUSB cable, to charge the devices that has a microUSB female port. I just simply call them USB chargers.

Most of these USB chargers can be characterized with the rated output voltage and current. Below are some that I have:

Device

Charger Voltage (V)

Charger Current (A)

LG Optimus V 5.1 0.70
Motorola DEFY XT 5.1 0.85
Samsung Galaxy Rush 5.0 1.00
Moto X 2nd Generation 5.0 1.15
Hisense SERO 7 Pro 5.0 2.00
Asus Transformer Book T100 5.0 2.00
HP Touchpad 5.3 2.00

As you can see, they have similar output voltages. Most of them have 5.0V rating. HP Touchpad has the highest output voltage, 5.3V. Their output currents can vary a lot though.

All the manufacturers warn that only their approved chargers can be used to charge the devices, to avoid damaging the device or charger. Of course this should be followed if possible. But I think we all have the chances that we want to just charge it with any convenient charger that we can grab close by. Can we do that?

USB Charging Basics

The USB interface has 4 wires/pins, Vcc(i.e., Vbus, +5V), D-, D+, Ground. Although USB was mainly designed for data communication, the presence of Vcc and Ground allows supplying power from one device to another device. The USB standard only allows the A-type socket to provide power. That’s why all these charges have a USB-A socket.

Any A-type socket may be ready to provide power, so it is dangerous to connect two A-type sockets using a USB A to A cable. That’s why most USB cables have only one A-type end; the other end is either B-type or micro-B type.

The device that receives power from USB normally have either USB-B type or microUSB-B type connector. In fact, ITU and other standard bodies endorse micro-B USB as data exchange and charging interface for the phones (and tablets). There are exceptions, such as Apple products that use the proprietary Lightning port, but they also provide microUSB to Lightning adaptors.

Connectivity aside, the actual charging involves drawing power in a way such that both the charger and the device agree. Unfortunately, this is very messy in the USB world. You can check The Basics of USB Battery Charging: A Survival Guide for details, but this is a short summary.

  • The dumbest charger/device just provides/draws power without any negotiation. The charger just leaves D+/D- float (not connected). The device may use D+/D- for data communication, but when in charging it does not check or makes no use of the two wires. Basically, it just uses USB as two wires and that’s it. This is not compliant to any USB standard. I suspect most cheap USB chargers are still like this.
  • USB 1.0/2.0 Power Specs. The initial USB 1.0/2.0 specs define two power supplying modes: 5V 100mA (Low Power) and 5V 500mA (High Power). A device can draw 100mA once connected to a USB power source; then it establishes USB digital data communication with the source through D+/D-, and use a digital protocol to negotiate with the source. It may be allowed to draw 500mA, or instructed to keep in the Low Power mode.
  • USB BC 1.1. The USB 1.0/2.0 Power Specs do not provide enough power to more power hungry devices, so a new spec, BC 1.1 comes to help. In BC 1.1, the device needs to check D+/D- (and sometimes additionally perform digital negotiation) to draw power from the source. There are three types of USB power sources:
    • Dedicated Charging Port (DCP). DCP internally shorts D+ and D- with a resistor of 0-200 Ohm. The device can detect the short and discover the source is a DCP. No digital communication is necessary. A DCP can supply up to 1.5A. DCP is still relatively dumb, and a lot of wall plug or car chargers belong to this category. A DCP does not perform data communication, i.e., is purely a power source.
    • Charging Downstream Port (CDP). A device needs to negotiate with CDP using hardware handshake through manipulating and monitoring D+/D- levels, however, no digital communication negotiation is needed. CDP can supply up to 1.5A. CDP powering and USB data communication can co-exist. Newer PCs and laptops have USB ports as CDPs to charge other devices.
    • Standard Downstream Port (SDP). SDP is basically the USB 1.0/2.0 Power Specs port (100mA or 500mA). BC 1.1 requires both D+ and D- to be grounded with 15k-25k Ohm resistor, and the device can detect that. From there, USB 1.0/2.0 Power Spec negotiation through digital communication is performed to determine whether possible to get to High Power mode. SDP powering and USB data communication can co-exist. Older PCs and laptops have USB ports as SDPs to charge other devices.
  • Manufacturer specific protocols
    • Apple chargers. Apple chargers pull D+/D- to certain levels, and Apple devices detect the levels to determine how much current to pull from the charger. See iCharging: The mysteries of Apple device charging for details.
    • Qualcomm Quick Charge. Qualcomm Quick Charge is open USB charging technology, see below.

A lot of USB wall chargers are dumbest chargers. The have arbitrary amperage ratings and non-5V voltage ratings, therefore are not conformant to the USB standards.

In general, higher charger output voltage means more capable in charging devices. For example, if I try to charge HP Touchpad with SERO 7 charger, most likely it would not charge anything, because the output voltage is just too low out of the charger. One the other hand, my HP Touchpad charger is the most powerful one and charges all the devices in my home. I was even successful in reviving almost dead battery of LG Optimus and breaking its boot loop as described in a previous post.

The output current dictates how fast the charger charges the device. For example, with the same output voltage, a 2.0A charger can charge 2 times as fast as a 1.0A charger. Normally more powerful devices have batteries of higher capacities, and use chargers with higher current ratings, so they do not need long time to recharge.

Asus Transformer Book T100 and BatteryBar

A lot of devices are also dumbest devices per USB charging. It draws power from the charger as long as it deems safe, without complying to the USB standards.

For some devices that try to be conformant, they may appear as picky ones, because they only draw a safe amount of current if they cannot determine the source type when the source is the dumbest charger.

The Asus Transformer Book T100 is 2-in-1 laptop/tablet that is “notorious” for picking chargers. Basically, its accompanying charger is slow in recharging the tablet. People try to use some other chargers with higher currents (and similar voltages), but they often find that it is charged even slower, drawing merely 500mA. Some people come up with mods to short D+ and D- in a dumbest charger, therefore per BC 1.1 DCP, T100 can draw up to 1.5A. Some other people report that not only T100 may be picky on chargers, but also picky on USB cables.

I am not sure if it’s really the different charging protocol, or just the voltage loss is too much on long USB cables of inferior quality (thinner metal wires therefore bigger resistance). And I do not want to modify my chargers. Luckily there is an application called BatteryBar in Windows, which can report the charging rate in real-time. BatteryBar Pro is $8, but I find the free BatteryBar Basic version is good enough for my purpose. It is only for Windows though.

Once installed, BatteryBar displays a toolbar on Windows bar. If you click it, it shows more information. While charging, the most important information is the wattage. For Asus T100 and HP Touchpad charger, I do find that a 6-feet-long USB cable would yield only about 2500mW (i.e., 500mA at 5V) charging, but a 3-feet-long USB cable would give about 5000mW (1000mA) charging. That’s a difference between 12+ hours and 6 hours for a full recharge. Asus T100 and Aukey Turbo Charger (see below) work at about 5000mW as well.

Qualcomm Quick Charge

Qualcomm’s Quick Charge technology provides another way to charge the devices faster by boosting the line voltage.

Qualcomm Quick Charge uses the same conventional USB A to microUSB-B cable. However, if both the charger and device are Quick Charge compliant, they can negotiate about faster charging. Quick Charge 1.0 allows up to 10W (5V/2A) charging. Quick Charge 2.0 can use various voltages up to 12V, at 3A current, the charging speed is 36W.

Similar to Apple charging protocols, Qualcomm Quick Charge uses the D+/D- levels to negotiate the charging speed. Below is an illustration (image courtesy Qualcomm Quick Charge 2.0 protocol specification and support).

Quick Charge 2.0 Specification Diagram

Devices using latest Snapdragon SoCs support Quick Charge 2.0, including phones and tablets. Other devices may support Quick Charge as well. You can check here for certified devices.

You can also find Quick Charge certified chargers here. Quick Charge 2.0 certified chargers can output different voltages. If you check the fine text on the charger, you will not see one voltage like 5V, but instead you will see 5V, 9V and 12V with respective current ratings. The key to charge faster is that the charger outputs high voltage with high current, and the device’s charging circuit would convert it to low voltage with even higher current to charge the battery.

As long as both charger and device conform to Quick Charge, they can come from different vendors. This should make you worry less when exchanging charges for your Quick Charge enabled device.

Qualcomm Quick Charge is backward compatible with conventional USB charging.

  • If the charger is conventional, Quick Charge device behaves like a conventional device, and charging is slow.
  • If the charger is Quick Charge certified but the device is conventional, charging falls back to 5V and is slow. Your device will not be fried.
  • If both charger and device are Quick Charge enabled, they negotiate at a high power charging and charging is fast.
  • Quick Charge 2.0 is also backward compatible with Quick Charge 1.0.

AndroidAuthority has a nice article explaining Quick Charge. The FAQ of Qualcomm Quick Charge can be found here.

The devices keep being more powerful and requiring larger battery capacity, and technologies like Quick Charge will be more popular. In fact, both Moto X 2nd Generation and Asus Transformer Book T100 supports Quick Charge 2.0, per device list. I just bought a Quick Charge certified Aukey charger off Amazon for a little over $10. This charger is able to output 12V/1.5A, i.e., 18W, which is promising.

image

In one occasion, the Aukey Turbo Charger charged Moto X2 from 5% to 42% in 20 minutes (both the phone and charger got hot). In the next 25 minutes, it continued to charge to 72%. This seems to be pretty good. It however yields only about 5000mW on Asus T100 according to BatteryBar.

Posted in Computer and Internet | Tagged: , , , , , , , , , , , , , , , | 1 Comment »

Delete Wireless Network Profile in Windows 8

Posted by binglongx on May 13, 2015

[memo]

If you cannot find “Forget this network” when you want to delete a Wi-Fi profile, just use the command line below:

netsh wlan delete profile name=”Your_SSID”

I use “Command Prompt (Admin)” from the Windows button to run the command above.

Reference:

How to Manage Wireless Network Connections & Profiles in Windows 8

Windows 8 – Manage Wireless Networks?

Posted in Computer and Internet | Tagged: , , , , , , , | Leave a Comment »

 
Follow

Get every new post delivered to your Inbox.

Join 51 other followers