Language: C++

#ifndef ___Geometry_Library
#define ___Geometry_Library

// ------ Includes ------ //
#include <cmath>
#include <complex>
#include <utility>
#include <algorithm>

// ------ Defines ------ //
typedef long double GType;
typedef std::complex<GType> Point;
typedef std::pair<Point, Point> Segment;

// ------ Constants ------ //
const GType EPS = 1.0e-10L;

// ------ Functions Level 1 ------ //
GType dot(const Point& p1, const Point& p2) {
	return (std::conj(p1) * p2).real();
}
GType cross(const Point& p1, const Point& p2) {
	return (std::conj(p1) * p2).imag();
}
int ccw(const Point& p1, const Point& p2, const Point& p3) {
	Point v1 = p2 - p1, v2 = p3 - p1;
	if (cross(v1, v2) > EPS) return +1;
	if (cross(v1, v2) < -EPS) return -1;
	if (dot(v1, v2) < -EPS) return +2;
	if (std::norm(v1) < std::norm(v2)) return -2;
	return 0;
}

// ------ Functions Level 2 ------ //
bool intersect(const Segment& s1, const Point& p1, bool segflag) {
	if (!segflag) return std::abs(cross(s1.second - p1, s1.first - p1)) < EPS;
	return (std::abs(s1.first - p1) + std::abs(s1.second - p1) - std::abs(s1.second - s1.first)) < EPS;
}
bool intersect(const Segment& s1, const Segment& s2, bool segflag) {
	if (!segflag) return cross(s1.second - s1.first, s2.first - s1.first) * cross(s1.second - s1.first, s2.second - s1.first) < EPS;
	return (ccw(s1.first, s1.second, s2.first) * ccw(s1.first, s1.second, s2.second)) <= 0 && (ccw(s2.first, s2.second, s1.first) * ccw(s2.first, s2.second, s1.second)) <= 0;
}
Point projection(const Segment& s1, const Point& p1) {
	GType mul = dot(p1 - s1.first, s1.first - s1.second) / norm(s1.first - s1.second);
	return s1.first + (s1.first - s1.second) * mul;
}
Point reflection(const Segment& s1, const Point& p1) {
	return p1 + (projection(s1, p1) - p1) * (GType)(2);
}
GType distance(const Point& p1, const Point& p2) {
	return std::abs(p2 - p1);
}
GType distance(const Segment& s1, const Point& p1, bool segflag) {
	if (!segflag) return std::abs(p1 - projection(s1, p1));
	const Point p2 = projection(s1, p1);
	if (intersect(s1, p2, true)) return std::abs(p2 - p1);
	return std::min(std::abs(s1.first - p1), std::abs(s1.second - p1));
}
GType distance(const Segment& s1, const Segment& s2, bool segflag) {
	if (intersect(s1, s2, segflag)) return 0;
	if (!segflag) return std::min(distance(s1, s2.first), distance(s1, s2.second));
	return std::min({ distance(s1, s2.first, false), distance(s1, s2.second, true), distance(s2, s1.first, true), distance(s2, s1.second, false) });
}

#endif

#include <iomanip>
#include <iostream>
using namespace std;
int q, xa, ya, xb, yb; Segment s1, s2;
int main() {
	cin >> q;
	while (q--) {
		cin >> xa >> ya >> xb >> yb; s1 = make_pair(Point(xa, ya), Point(xb, yb));
		cin >> xa >> ya >> xb >> yb; s2 = make_pair(Point(xa, ya), Point(xb, yb));
		cout << fixed << setprecision(15) << distance(s1, s2, true) << endl;
	}
	return 0;
}

Compiler output:
a.cc: In function 'GType distance(const Segment&, const Segment&, bool)':
a.cc:61:47: error: no matching function for call to 'distance(const Segment&, const std::complex<long double>&)'
   61 |         if (!segflag) return std::min(distance(s1, s2.first), distance(s1, s2.second));
      |                                       ~~~~~~~~^~~~~~~~~~~~~~
In file included from /usr/include/c++/14/bits/stl_algobase.h:66,
                 from /usr/include/c++/14/bits/specfun.h:43,
                 from /usr/include/c++/14/cmath:3906,
                 from a.cc:5:
/usr/include/c++/14/bits/stl_iterator_base_funcs.h:148:5: note: candidate: 'template<class _InputIterator> constexpr typename std::iterator_traits< <template-parameter-1-1> >::difference_type std::distance(_InputIterator, _InputIterator)'
  148 |     distance(_InputIterator __first, _InputIterator __last)
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator_base_funcs.h:148:5: note:   template argument deduction/substitution failed:
a.cc:61:47: note:   deduced conflicting types for parameter '_InputIterator' ('std::pair<std::complex<long double>, std::complex<long double> >' and 'std::complex<long double>')
   61 |         if (!segflag) return std::min(distance(s1, s2.first), distance(s1, s2.second));
      |                                       ~~~~~~~~^~~~~~~~~~~~~~
a.cc:50:7: note: candidate: 'GType distance(const Point&, const Point&)'
   50 | GType distance(const Point& p1, const Point& p2) {
      |       ^~~~~~~~
a.cc:50:29: note:   no known conversion for argument 1 from 'const Segment' {aka 'const std::pair<std::complex<long double>, std::complex<long double> >'} to 'const Point&' {aka 'const std::complex<long double>&'}
   50 | GType distance(const Point& p1, const Point& p2) {
      |                ~~~~~~~~~~~~~^~
a.cc:53:7: note: candidate: 'GType distance(const Segment&, const Point&, bool)'
   53 | GType distance(const Segment& s1, const Point& p1, bool segflag) {
      |       ^~~~~~~~
a.cc:53:7: note:   candidate expects 3 arguments, 2 provided
a.cc:59:7: note: candidate: 'GType distance(const Segment&, const Segment&, bool)'
   59 | GType distance(const Segment& s1, const Segment& s2, bool segflag) {
      |       ^~~~~~~~
a.cc:59:7: note:   candidate expects 3 arguments, 2 provided
a.cc:61:71: error: no matching function for call to 'distance(const Segment&, const std::complex<long double>&)'
   61 |         if (!segflag) return std::min(distance(s1, s2.first), distance(s1, s2.second));
      |                                                               ~~~~~~~~^~~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_iterator_base_funcs.h:148:5: note: candidate: 'template<class _InputIterator> constexpr typename std::iterator_traits< <template-parameter-1-1> >::difference_type std::distance(_InputIterator, _InputIterator)'
  148 |     distance(_InputIterator __first, _InputIterator __last)
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator_base_funcs.h:148:5: note:   template argument deduction/substitution failed:
a.cc:61:71: note:   deduced conflicting types for parameter '_InputIterator' ('std::pair<std::complex<long double>, std::complex<long double> >' and 'std::complex<long double>')
   61 |         if (!segflag) return std::min(distance(s1, s2.first), distance(s1, s2.second));
      |                                                               ~~~~~~~~^~~~~~~~~~~~~~~
a.cc:50:7: note: candidate: 'GType distance(const Point&, const Point&)'
   50 | GType distance(const Point& p1, const Point& p2) {
      |       ^~~~~~~~
a.cc:50:29: note:   no known conversion for argument 1 from 'const Segment' {aka 'const std::pair<std::complex<long double>, std::complex<long double> >'} to 'const Point&' {aka 'const std::complex<long double>&'}
   50 | GType distance(const Point& p1, const Point& p2) {
      |                ~~~~~~~~~~~~~^~
a.cc:53:7: note: candidate: 'GType distance(const Segment&, const Point&, bool)'
   53 | GType distance(const Segment& s1, const Point& p1, bool segflag) {
      |       ^~~~~~~~
a.cc:53:7: note:   candidate expects 3 arguments, 2 provided
a.cc:59:7: note: candidate: 'GType distance(const Segment&, const Segment&, bool)'
   59 | GType distance(const Segment& s1, const Segment& s2, bool segflag) {
      |       ^~~~~~~~
a.cc:59:7: note:   candidate expects 3 arguments, 2 provided